home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_c / alib12 / manual.doc < prev    next >
Text File  |  1992-03-29  |  187KB  |  5,412 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.                               Reference Manual for the
  14.                               AutoLibrary(tm) Program-Playback Tool
  15.  
  16.                               Version 1.2
  17.                               March 1992
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.                               Copyright 1991 by
  26.                               Wayne E. McDaniel
  27.                               All Rights Reserved
  28.  
  29.                               AutoLibrary(tm) is a Trademark of
  30.                               Avid Software
  31.  
  32.                               Avid Software
  33.                               P.O. Box 1871 
  34.                               Beaverton, OR  97075-1871
  35.  
  36.                               (503) 626-6652
  37.  
  38.                               CompuServe Mail:    70372,2513
  39.                               Internet:           70372.2513@compuserve.com
  40.  
  41.  
  42.                                _______ 
  43.                           ____|__     |               (tm) 
  44.                        --|       |    |------------------- 
  45.                          |   ____|__  |  Association of 
  46.                          |  |       |_|  Shareware 
  47.                          |__|   o   |    Professionals 
  48.                        -----|   |   |--------------------- 
  49.                             |___|___|    MEMBER 
  50.  
  51.  
  52.  
  53.  
  54.           Copyright 1991 Wayne E. McDaniel,  All rights reserved.  Printed
  55.           in the United States of America.
  56.  
  57.           The AutoLibrary(tm) Program-Playback tool Shareware diskette,
  58.           which contains a copy of this manual, may be freely copied and
  59.           shared.  
  60.  
  61.           However, multiple copies of this document may not be printed and
  62.           printed copies of this document may not be copied in any way
  63.           without permission in writing from Avid Software.
  64.  
  65.  
  66.  
  67.  
  68.                                   Table of Contents
  69.  
  70.           Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   4
  71.  
  72.           Installation  . . . . . . . . . . . . . . . . . . . . . . . .   8
  73.  
  74.           System Requirements . . . . . . . . . . . . . . . . . . . . .   9
  75.  
  76.           Optional Requirements . . . . . . . . . . . . . . . . . . . .   9
  77.  
  78.           Discussion of Requirements  . . . . . . . . . . . . . . . . .   9
  79.  
  80.           Compiling Source  . . . . . . . . . . . . . . . . . . . . . .   9
  81.  
  82.           Compiling Interface Libraries . . . . . . . . . . . . . . . .   9
  83.  
  84.           Compiling Applications  . . . . . . . . . . . . . . . . . . .  10
  85.  
  86.           Getting Started Using Example 1 (ex01.exe)  . . . . . . . . .  11
  87.  
  88.           Getting Started Using Example 2 (ex02.exe)  . . . . . . . . .  14
  89.  
  90.           A Tutorial  . . . . . . . . . . . . . . . . . . . . . . . . .  15
  91.  
  92.           Reference Guide For the AutoLibrary(tm) Program-Playback
  93.                tool . . . . . . . . . . . . . . . . . . . . . . . . . .  33
  94.                AvidClosePort - Close Communication Port . . . . . . . .  34
  95.                AvidConvert - Convert Characters to Strings  . . . . . .  36
  96.                AvidDrainPort - Drain Communication Port . . . . . . . .  38
  97.                AvidExitAutoLibrary - Exit AutoLibrary . . . . . . . . .  41
  98.                AvidGetFromHoldArea - Get Characters from Hold Area  . .  43
  99.                AvidInitAutoLibrary - Initialize AutoLibrary . . . . . .  45
  100.                AvidLogInfo - Log information to file or screen. . . . .  47
  101.                AvidLogOpen - Open a Log File. . . . . . . . . . . . . .  51
  102.                AvidOpenPort - Open Communication Port . . . . . . . . .  53
  103.                AvidProcessOptions - Parse an Option Parameter List  . .  57
  104.                AvidRead - Read a Character  . . . . . . . . . . . . . .  60
  105.                AvidRegisterSend - Register a String to Send . . . . . .  63
  106.                AvidRegisterWait - Register a Wait String  . . . . . . .  65
  107.                AvidSend - Send a String . . . . . . . . . . . . . . . .  67
  108.                AvidSendSearch - Send Strings then Search  . . . . . . .  69
  109.                AvidVersion - Print Version and Copyright Information  .  76
  110.                EveryChar - Called with Every Character Received . . . .  77
  111.  
  112.           Reference Guide for Interface Routines  . . . . . . . . . . .  79
  113.                CommInterfaceClose - Close port  . . . . . . . . . . . .  80
  114.                CommInterfaceOpen - Open Port  . . . . . . . . . . . . .  82
  115.                CommInterfaceRead - Read Character . . . . . . . . . . .  94
  116.                CommInterfaceSend - Send Character . . . . . . . . . . . 105
  117.  
  118.  
  119.  
  120.                                                                           4
  121.  
  122.  
  123.           Introduction
  124.  
  125.           The AutoLibrary(tm) Program-Playback tool is a C function library
  126.           for automation.  Automation is coded into programs then played
  127.           back when the program executes.
  128.  
  129.           This tool will not replace any of your existing automation tools. 
  130.           You will still use your terminal emulator's script language for
  131.           automatic access to bulletin boards and online services and you
  132.           may still want your Capture-Playback tool to create quick and
  133.           convenient regression tests.
  134.  
  135.           Instead of replacing any tool, add this tool to your personal
  136.           tool box and use it when it offers the best solution.
  137.  
  138.           To determine if this tool offers you the best solution, consider
  139.           the following questions.
  140.  
  141.                1.   Is there a serial connection to the system being
  142.                     automated?  Or can there be by redirecting I/O or
  143.                     designing in a serial test port?
  144.  
  145.                2.   Are you automating with ASCII characters?
  146.  
  147.                3.   Do you want C as your programming language, where
  148.                     automation is hand coded into subroutines?
  149.  
  150.           If your answers to the previous questions were yes, you will
  151.           need...
  152.  
  153.                1.   A PC with a serial port.
  154.  
  155.                2.   Turbo C version 2.0
  156.  
  157.           Or you will need to do one or more of the following...
  158.  
  159.                1.   Port this to a different operating system.
  160.  
  161.                2.   Port the interface routines to something other than RS-
  162.                     232.
  163.  
  164.                3.   Port the interface routines to a different
  165.                     communications package.
  166.  
  167.                4.   Port to a different C compiler.
  168.  
  169.           The features of this tool combined with the C programming
  170.           language, give you the benefit of writing easy and flexible
  171.  
  172.  
  173.  
  174.                                                                           5
  175.  
  176.           automation programs.  The following list shows some of the
  177.           features and benefits you will like.
  178.  
  179.                1.   Your automation programs can be distributed without
  180.                     script files or interpreters.
  181.  
  182.                2.   Your automation programs will take advantage of the C
  183.                     programming language for many things like:  file I/O,
  184.                     flow control, variable declarations, parameterized
  185.                     subroutines, and so on.  Also, you can take advantage
  186.                     of C debuggers, profilers, linkers, and other add-on
  187.                     libraries.  You will be able to create generic
  188.                     automation libraries using the C librarian for
  189.                     distribution to other members of your group.
  190.  
  191.                3.   Your automation programs will not have to depend on
  192.                     play back timing or comparisons to previous runs. 
  193.                     Instead, your automation programs will have the
  194.                     expected results coded in.
  195.  
  196.                4.   Your automation programs will take advantage of the way
  197.                     this tool handles timeouts.
  198.  
  199.                     There are two types of timeouts: Repeating-Timeouts and
  200.                     Ending-Timeouts.  Repeating timeouts start over after
  201.                     each newly received character and ending timeouts
  202.                     don't.
  203.  
  204.                5.   Your automation programs will handle variations of
  205.                     play-back input by registering multiple strings to wait
  206.                     for.
  207.  
  208.                6.   Your automation programs will take advantage of the
  209.                     options parameter each routine has.  This parameter
  210.                     allows customized use of the routines.  It will also
  211.                     allow me to add functionality without adding new
  212.                     interfaces or changes existing ones.
  213.  
  214.                7.   Your automation programs may take advantage of the
  215.                     EveryChar routine.  This routine is written by you and
  216.                     is called with each received character.
  217.  
  218.                8.   Your automation programs may take advantage of your
  219.                     ability to vary the send delay between each character
  220.                     sent.
  221.  
  222.  
  223.  
  224.                                                                           6
  225.  
  226.  
  227.           The following lists each of the routines in this tool...
  228.  
  229.           The main routines that support automation sequences...
  230.  
  231.                AvidRegisterSend - Register a string to send.
  232.                AvidRegisterWait - Register a wait string.
  233.                AvidSendSearch - Send strings then search.
  234.  
  235.           The others in alphabetical order...
  236.  
  237.                AvidClosePort - Close communication port.
  238.                AvidConvert - Convert characters to strings.
  239.                AvidDrainPort - Drain communications port.
  240.                AvidExitAutoLibrary - Exit AutoLibrary.
  241.                AvidGetFromHoldArea - Get characters from hold area.
  242.                AvidInitAutoLibrary - Initialize AutoLibrary.
  243.                AvidLogInfo - Log information to file or screen.
  244.                AvidLogOpen - Open a log file.
  245.                AvidOpenPort - Open communication port.
  246.                AvidProcessOptions - Parse an option parameter list.
  247.                AvidRead - Read a character.
  248.                AvidSend - Send a string.
  249.                AvidVersion - Print version and copyright information.
  250.                EveryChar - Called with every character received.
  251.  
  252.           Interface routines to your communications library...
  253.  
  254.                CommInterfaceClose - Close port.
  255.                CommInterfaceOpen - Open port.
  256.                CommInterfaceRead - Read Character.
  257.                CommInterfaceSend - Send Character.
  258.  
  259.  
  260.  
  261.                                                                           7
  262.  
  263.  
  264.           The following list shows some of the applications this tool would
  265.           be good for.  (The items with an asterisk are projects that I
  266.           have done using this automation technique.)
  267.  
  268.                -    Automating CompuServe access.
  269.                -    Controlling/testing a modem.
  270.                -    Controlling/testing an ASCII Terminal
  271.                -    Controlling/testing Unix or a program running on Unix.
  272.                -    Controlling/testing other mini or mainframe computer
  273.                     systems.
  274.                -    Controlling/testing Bulletin Board Systems
  275.                -    Controlling/testing Data Switches.
  276.                -  * Network monitoring from users perspective.
  277.                -    Controlling/testing Special equipment.  For example,
  278.                     medical instruments.  Especially instruments that have
  279.                     serial ports designed in to help support automated
  280.                     testing. 
  281.                -  * Controlling/testing Target debug monitors.
  282.                -    Controlling/testing Prom programmers.
  283.  
  284.                -    Controlling/testing anything that has a serial
  285.                     connection or can be redirected through a serial
  286.                     connection.
  287.  
  288.  
  289.  
  290.                                                                           8
  291.  
  292.  
  293.           Installation
  294.  
  295.           For installation instructions see the readme file for installing
  296.           this software.
  297.  
  298.           Please see the PACKAGE.LST file for a description of CONSULT.DOC,
  299.           SUPPORT.DOC, LICENSE.DOC, and so on.  Within these files are
  300.           important information about registering, warranty, support,
  301.           license agreements, vendor/sysop information, hiring me as a
  302.           contractor/consultant, and so on.
  303.  
  304.  
  305.  
  306.                                                                           9
  307.  
  308.  
  309.           System Requirements
  310.  
  311.           a)   Turbo C v2.0
  312.           b)   COM 1 or COM 2
  313.           c)   IBM PC or compatible
  314.  
  315.  
  316.           Optional Requirements
  317.  
  318.           a)   A communication package, such as, Greenleaf Comm Library
  319.                v2.21  (Should work with v3.0)
  320.  
  321.  
  322.           Discussion of Requirements
  323.  
  324.           The AutoLibrary Program-Playback Tool communicates via interface
  325.           routines to the communication package.  I provide a basic
  326.           asynchronous RS-232 communication package with this tool to get
  327.           you started.  However, I recommend using a communication package
  328.           with additional features and a proven track record.
  329.  
  330.           Interface routines are provided for the Greenleaf Comm Library. 
  331.           However, you may port the interface routines to any one of the
  332.           many communication packages.  This manual contains detailed
  333.           instructions for doing this.
  334.  
  335.           It is possible for both registered and unregistered users to
  336.           write interface routines for a different communication package. 
  337.  
  338.           Also, given registered user receive the source, it is possible to
  339.           port this tool to other compilers and operating systems.
  340.  
  341.  
  342.           Compiling Source
  343.  
  344.           The source code is generated by the batch file genauto.bat.  Make
  345.           sure Turbo C is located in \tc or edit the batch files with your
  346.           Turbo C path.
  347.  
  348.  
  349.           Compiling Interface Libraries
  350.  
  351.           The interface libraries are generated by the batch file
  352.           genface.bat.  Make sure Turbo C is located in \tc and the
  353.           Greenleaf Comm Library is located in \gls or edit the batch files
  354.           with your pathnames.
  355.  
  356.  
  357.  
  358.                                                                          10
  359.  
  360.           Please see the detailed information on how to port the interface
  361.           routines to use other communication packages.  The information is
  362.           documented in the reference section for CommInterfaceClose,
  363.           CommInterfaceOpen, CommInterfaceRead, and CommInterfaceSend.
  364.  
  365.  
  366.           Compiling Applications
  367.  
  368.           To compile your application, I recommend starting with example
  369.           one in the self-extracting file ex01.exe.  Copy this file to a
  370.           clean directory, then execute ex01.  Here you will find a
  371.           template file ready to compile with genex01.bat.
  372.  
  373.  
  374.  
  375.                                                                          11
  376.  
  377.  
  378.           Getting Started Using Example 1 (ex01.exe)
  379.  
  380.           The goal of this section is to provide you with a simple example
  381.           to get you started.  Also, to help you get started, read the
  382.           tutorial section.  This will give you an overview of how to
  383.           automate using the AutoLibrary(tm) Program-Playback tool.  You
  384.           may run the Wyse demo if it is convenient, i.e., if you have a
  385.           Wyse terminal handy.  Regardless of whether you are able to run
  386.           the Wyse demo, I recommend doing a quick code review of the demo. 
  387.           Start with example 1 and then look at example 2.  The examples
  388.           are in self-extracting files ex01.exe and ex02.exe.  Execute
  389.           these programs in clean directories to extract the files.
  390.  
  391.           When getting started with something new, it is nice to know the
  392.           minimum that is required.  Therefore, I have supplied a template
  393.           file (template.c from ex01.exe) that contains the minimum
  394.           required for the AutoLibrary(tm) Program-Playback tool.  The
  395.           following code is a listing of template.c.
  396.  
  397.  
  398.  
  399.                                                                          12
  400.  
  401.  
  402.           /* template.c */
  403.  
  404.           #include <stdio.h>
  405.           #include <stdlib.h>
  406.           #include <string.h>
  407.  
  408.           #include "al.h"
  409.  
  410.           /*****/
  411.           void EveryChar(c)
  412.           int c;
  413.           /*****/
  414.           {
  415.               /* Print each character received. */
  416.               printf("%c", c);
  417.           }
  418.  
  419.           /*****/
  420.           void main(argc, argv)
  421.           /*****/
  422.           int argc;
  423.           char *argv[];
  424.           {
  425.           int com;
  426.           int err, add_info;
  427.  
  428.               argc = argc; /* for compiler. */
  429.               argv = argv; /* for compiler. */
  430.  
  431.               /* Initial AutoLibrary. */
  432.               AvidInitAutoLibrary(AVID, &add_info, "_B'3'");
  433.  
  434.               /* Open the communication port. */
  435.               com = AvidOpenPort(AVID, "com1", &add_info,
  436.                                                ".b'9600' .1 .8 .n +S -H");
  437.  
  438.               /* Display AutoLibrary version. */
  439.               AvidVersion(AVID, &add_info, "");
  440.  
  441.               /* Ready for automation. */
  442.  
  443.               /* Finished so close the com port. */
  444.               AvidClosePort(AVID, com, &add_info, "");
  445.  
  446.               /* Exit from AutoLibrary. */
  447.               AvidExitAutoLibrary(AVID, &add_info, "");
  448.           }
  449.  
  450.  
  451.  
  452.                                                                          13
  453.  
  454.           The above template program has been supplied with this product
  455.           and can be compiled.  If the following automation sequence was
  456.           added to the template file, it would send "Hello World" to
  457.           whatever the PC was connected to.  Then it would wait for the
  458.           string "Hello Back".
  459.  
  460.           AvidRegisterSend(AVID, com, "Hello World", &add_info, "");
  461.           AvidRegisterWait(AVID, com, 1, "Hello Back", &add_info, "");
  462.           if ((AvidSendSearch(AVID, com,(long)20, (long)120,
  463.                                                     &add_info, "")) == 1)
  464.               printf("Found Hello Back.\n");
  465.           else
  466.               printf("Timeout occurred.\n");
  467.  
  468.           If you add this code and connect your PC to a terminal or a PC
  469.           running terminal emulation software, you will see the "Hello
  470.           World" string printed.  Then, from the terminal or PC running
  471.           terminal emulation software, you can type in the string "Hello
  472.           Back", which would result in a successful automation sequence.
  473.  
  474.           This example is small, but it gives you a feel for how automation
  475.           works.  A command string is sent out, then one or more strings
  476.           are scanned for.
  477.  
  478.           Note that this example is a bit odd.  Normally, automation
  479.           programs are connected to programs or equipment that can
  480.           communicate on there own.  For this example, you simulated
  481.           something being automated when you typed in "Hello Back".
  482.  
  483.  
  484.  
  485.                                                                          14
  486.  
  487.  
  488.           Getting Started Using Example 2 (ex02.exe)
  489.  
  490.           To run the wyse terminal demo you will need to connect
  491.           communication port one (com1) of a PC to a Wyse 30, Wyse 50, or
  492.           Wyse 60.  For a Wyse 60 terminal, invoke the setup and select the
  493.           Wyse 50 compatibility mode.  When connecting the PC to the
  494.           terminal, a null modem may be required.
  495.  
  496.           The wyse terminal demo is executed from a command line interface
  497.           that works much like a Unix utility.  The code in wyse1.c is the
  498.           program control code, where as, the code in wyse.c is the
  499.           automation routines.
  500.  
  501.           By typing in 'wyse' (without options), a help screen is
  502.           displayed.  For example...
  503.  
  504.           C:\EX02\>wyse
  505.  
  506.           Usage: wyse <options>
  507.  
  508.           Where: <options> are...
  509.           +a --- Run all tests.
  510.           .A --- Abort program if an error occurs. (Default is continue)
  511.           -L --- Run long version of tests.
  512.           +p --- Run protected mode test.
  513.           -a --- Run screen attributes test.
  514.           +s --- Run screen location test.
  515.           +P --- Run screen print test.
  516.  
  517.           The following will run all of the tests and abort if there is an
  518.           error.
  519.  
  520.           C:\EX02\>wyse +a .A
  521.  
  522.           The following will run the Screen Attributes test and the
  523.           Protected Mode test.  The long versions of these tests will be
  524.           run if they exist.
  525.  
  526.           C:\EX02\>wyse -a +p -L
  527.  
  528.           One of the tests has been coded to purposely report errors.  This
  529.           will demonstrate what error messages look like.
  530.  
  531.  
  532.  
  533.                                                                          15
  534.  
  535.  
  536.           A Tutorial
  537.  
  538.           The goal of this tutorial is to introduce you to automation using
  539.           the AutoLibrary(tm) Program-Playback tool.
  540.  
  541.           This tutorial uses a PC and a Wyse 50 terminal.  The serial
  542.           connection between the PC and the Wyse 50 terminal places the PC
  543.           in the unusual role of "host computer."  On the other hand,
  544.           everything seems normal to the terminal, which displays
  545.           characters when received and sends characters when typed in.  The
  546.           Wyse 50 does not know it is connected to a PC.
  547.  
  548.           Once the PC and Wyse 50 are connected, we can write automation
  549.           routines that send and receive from the terminal.  This tutorial
  550.           focuses on a Wyse 50 command that allows host computers to
  551.           identify the terminal.  The command has the format "ESC<space>",
  552.           and is one of many Wyse 50 escape codes.  When the Wyse 50
  553.           receives this command, it returns the string "50\r".  The '\r'
  554.           character is the C notation for a return character.  The
  555.           following code segment is the first of many that will use the
  556.           "ESC<space>" escape command to illustrate automation techniques
  557.           using the AutoLibrary(tm) Program-Playback tool.
  558.  
  559.           sprintf(temp_s, "%s ", ESC_CODE);
  560.           AvidRegisterSend(AVID, com, temp_s, &add_info, "");
  561.           AvidRegisterWait(AVID, com, 1, "50", &add_info, "");
  562.  
  563.           register_value = AvidSendSearch(AVID,
  564.                                     com,(long)5, (long)10, &add_info, "");
  565.  
  566.           The calls to AvidRegisterSend and AvidRegisterWait result in two
  567.           linked lists being built for AvidSendSearch: the send-list and
  568.           the wait-list.  The call to AvidRegisterSend does not actually
  569.           send the string.  Instead, AvidSendSearch sends all of the
  570.           strings in the send-list and then begins a search for the strings
  571.           in the wait-list.
  572.  
  573.           In this example, AvidSendSearch sends the command "ESC<space>" to
  574.           the Wyse 50 terminal, then begins a search for the string "50". 
  575.           The value returned depends on the outcome of the search.  If the
  576.           string "50" is found, the return value will be 1.  If the string
  577.           "50" is not found, the value 0 will be returned.  Zero is always
  578.           returned when none of the strings in the wait-list are found. 
  579.           Notice, when the string is found, the returned value depends on
  580.           what was registered.  In this example, the string "50" was
  581.           registered with 1.  It could have been registered with the value
  582.           527, which would cause AvidSendSearch to return 527 when the
  583.           string was found.
  584.  
  585.  
  586.  
  587.                                                                          16
  588.  
  589.  
  590.           It is possible to register more than one string in the send-
  591.           list.  However, this is not done very often, since complicated
  592.           send strings can be built using 'sprintf'.  It is different for
  593.           the wait-list.  Your programs will have multiple wait strings
  594.           many times.  Since the Wyse 30, Wyse 50, and Wyse 60 have
  595.           compatibility modes, it makes sense to write the above sample
  596.           code segment as follows.
  597.  
  598.           sprintf(temp_s, "%s ", ESC_CODE);
  599.           AvidRegisterSend(AVID, com, temp_s, &add_info, "");
  600.  
  601.           AvidRegisterWait(AVID, com, 1, "30", &add_info, "");
  602.           AvidRegisterWait(AVID, com, 2, "50", &add_info, "");
  603.           AvidRegisterWait(AVID, com, 3, "60", &add_info, "");
  604.  
  605.           register_value = AvidSendSearch(AVID, com,
  606.                                         (long)5, (long)10, &add_info, "");
  607.  
  608.           Nothing is different except for the two additional calls to
  609.           AvidRegisterWait.  These calls allow AvidSendSearch to search for
  610.           the strings "30", "50", and "60" at the same time. 
  611.           AvidSendSearch will return 1 if connected to a Wyse 30, 2 if
  612.           connected to a Wyse 50, and 3 for a Wyse 60.  ERR_SNF (Zero) is
  613.           returned if none of these terminals are connected.
  614.  
  615.           Now, suppose the PC's serial port is disconnected.  Given the
  616.           above code segment, AvidSendSearch will timeout and return
  617.           ERR_SNF (String-Not-Found).
  618.  
  619.           The AutoLibrary(tm) Program-Playback tool supports two types of
  620.           timeouts:  A Repeating Timeout and an Ending Timeout.  Before
  621.           defining repeating and ending timeouts, notice that the basic
  622.           model of automation requires timeouts.  Automation is
  623.           programmatically sending a keystroke sequence, then scanning the
  624.           output for a list of expected responses.  When none of the
  625.           expected responses are found, a timeout must occur.  The program
  626.           will enter an endless loop without a timeout feature.
  627.  
  628.           A repeating timeout starts over after each received character. 
  629.           Therefore, if a repeating timeout of 10 seconds is specified, the
  630.           timeout will not occur unless there is communication silents for
  631.           10 seconds.  A timeout will never occur if characters are
  632.           continuously received.  An ending timeout, on the other hand, is
  633.           not reset with each newly received character.  If an ending
  634.           timeout of 20 seconds is specified, a timeout will occur in 20
  635.           seconds regardless, assuming none of the expected responses are
  636.           received.
  637.  
  638.  
  639.  
  640.                                                                          17
  641.  
  642.           These two types of timeouts can play an important role in writing
  643.           correct automation "scripts."  The repeating timeout can be given
  644.           a reasonable timeout value and still be able to handle many
  645.           variations in input.  The ending timeout can be given a large
  646.           value, which could indicate an error condition.  When
  647.           AvidSendSearch returns ERR_SNF due to a timeout, the return
  648.           parameter 'add_info' will be set to ERR_ENDING_TIMEOUT or
  649.           ERR_REPEAT_TIMEOUT.
  650.  
  651.           A topic that is related to timeouts is draining communication
  652.           ports.  Draining a communication port is simply reading in
  653.           characters while ignoring them for a specified amount of time. 
  654.           The time period to drain a communication port can be a Repeating
  655.           Drain and an Ending Drain.  A repeating drain starts over with
  656.           each newly received character.  There needs to be communication
  657.           silents for repeating drains to stop.  An ending drain will stop
  658.           after the specified amount of time regardless of communication
  659.           activity.
  660.  
  661.           The following is the same sample code segment with the additional
  662.           call to AvidDrainPort.
  663.  
  664.           sprintf(temp_s, "%s ", ESC_CODE);
  665.           AvidRegisterSend(AVID, com, temp_s, &add_info, "");
  666.  
  667.           AvidRegisterWait(AVID, com, 1, "30", &add_info, "");
  668.           AvidRegisterWait(AVID, com, 2, "50", &add_info, "");
  669.           AvidRegisterWait(AVID, com, 3, "60", &add_info, "");
  670.  
  671.           register_value = AvidSendSearch(AVID, com,
  672.                                         (long)5, (long)10, &add_info, "");
  673.  
  674.           AvidDrainPort(AVID, com, (long)1, (long)3, &add_info, "");
  675.  
  676.           This drains the communication port of the <cr> character. 
  677.           Remember that when a Wyse 50 terminal receives the "ESC<space>"
  678.           command, it returns "50<cr>".   However, the wait-list contains
  679.           only the string "50", which causes the <cr> character not to be
  680.           read in.  To guard against the <cr> character effecting the next
  681.           automation sequence, it is drained.
  682.  
  683.           Another way to make sure the <cr> is read in, is to include it in
  684.           the wait string.  The following example demonstrates this.
  685.  
  686.           sprintf(temp_s, "%s ", ESC_CODE);
  687.           AvidRegisterSend(AVID, com, temp_s, &add_info, "");
  688.  
  689.           AvidRegisterWait(AVID, com, 1, "30\r", &add_info, "");
  690.           AvidRegisterWait(AVID, com, 2, "50\r", &add_info, "");
  691.  
  692.  
  693.  
  694.                                                                          18
  695.  
  696.           AvidRegisterWait(AVID, com, 3, "60\r", &add_info, "");
  697.  
  698.           register_value = AvidSendSearch(AVID, com,
  699.                                         (long)5, (long)10, &add_info, "");
  700.  
  701.           You will notice the call to AvidDrainPort is gone and the '\r'
  702.           character has been added to the wait strings.  For this example,
  703.           adding the '\r' character is better than calling AvidDrainPort,
  704.           only because the one second delay in AvidDrainPort is avoided. 
  705.           The two methods, otherwise, result in the same thing.
  706.  
  707.           In general, draining is needed when there are leftover characters
  708.           after an automation sequence has finished.  In the above example,
  709.           the '\r' was a leftover character.  You will find draining
  710.           communication ports very useful when the leftover characters of
  711.           an automation sequence varies.
  712.  
  713.           The following code segment will be familiar by now.  It sends the
  714.           "ESC<space>" command to the Wyse 50 terminal then scans for the
  715.           string "50".  When finished, the '\r' character is drained.
  716.  
  717.           sprintf(temp_s, "%s ", ESC_CODE);
  718.           AvidRegisterSend(AVID, com, temp_s, &add_info, "");
  719.  
  720.           AvidRegisterWait(AVID, com, 1, "50", &add_info, "");
  721.  
  722.           register_value = AvidSendSearch(AVID, com,
  723.                                         (long)5, (long)10, &add_info, "");
  724.  
  725.           AvidDrainPort(AVID, com, (long)1, (long)3, &add_info, "");
  726.  
  727.           The following code segment works the same way as above, but uses
  728.           switches instead.
  729.  
  730.           sprintf(temp_s, ".s'%s ' 1w'50' .d'1'", ESC_CODE);
  731.           value = AvidSendSearch(AVID, com, (long)5, (long)10,
  732.                                                        &add_info, temp_s);
  733.  
  734.           With switches, the same automation sequence can be accomplished
  735.           with one call to AvidSendSearch.  The .s'%s ' switch adds the
  736.           "ESC<space>" string to the send-list, the 1w'50' switch adds the
  737.           string "50" to the wait-list, and the switch .d'1' indicates
  738.           there is to be a drain after the automation sequence has
  739.           finished.  These switches replace the need to call
  740.           AvidRegisterSend, AvidRegisterWait, and AvidDrainPort explicitly.
  741.           Here is the same call again with two additional wait strings.
  742.  
  743.  
  744.  
  745.                                                                          19
  746.  
  747.  
  748.           sprintf(temp_s, ".s'%s ' 7w'30' 6w'50' 9w'60' .d'1'", ESC_CODE);
  749.           value = AvidSendSearch(AVID, com, (long)5, (long)10,
  750.                                                        &add_info, temp_s);
  751.  
  752.           In this example, AvidSendSearch will send the "ESC<space>"
  753.           command then search for the strings "30", "50", and "60".  If the
  754.           string "30" is found, AvidSendSearch returns 7, if "50" is found,
  755.           6 is returned and if "60" is found, 9 will be returned.
  756.  
  757.           Notice that the switch .D'3' would also be required to make the
  758.           switched version match the unswitched version exactly.  The .d'1'
  759.           switch causes a Repeating Drain for one second and the .D'3'
  760.           would cause a 3 second Ending Drain.
  761.  
  762.           The "ESC<space>" command would make a nice general purpose
  763.           routine that other parts of the automation program could call. 
  764.           Here is a boolean function that returns TRUE if a Wyse 30, 50, or
  765.           60 is connected and FALSE if not.
  766.  
  767.           /****************/
  768.           int wyse_terminal(com)
  769.           int com;
  770.           /****************/
  771.           {
  772.           char temp_s[85];
  773.           int err;
  774.           int add_info;
  775.  
  776.               /*
  777.                  Test to see if connected to a Wyse terminal.
  778.                  Use the command  ESC<space>
  779.                  Where:
  780.                  <space> is a blank space.
  781.  
  782.                  The Wyse terminal will return 30\r, 50\r, or 60\r
  783.               */
  784.  
  785.               sprintf(temp_s, ".s'%s ' 1w'30' 2w'50' 3w'60' .d'1'",        
  786.                                                         ESC_CODE);
  787.               if ((err = AvidSendSearch(AVID, com, (long)1, (long)3,
  788.                                           &add_info, temp_s)) <= ERR_SNF)
  789.                   return(FALSE);
  790.               else
  791.                   return(TRUE);
  792.           }
  793.  
  794.           Since all error codes are returned as negative numbers, the test
  795.           for less than or equal to ERR_SNF will work fine.  This just
  796.  
  797.  
  798.  
  799.                                                                          20
  800.  
  801.           means that FALSE will be returned if none of the strings in the
  802.           wait-list are found or an error is returned by AvidSendSearch. 
  803.           TRUE will be returned if AvidSendSearch returns 1, 2, or 3. 
  804.           Other parts of the program would then be able to make calls like
  805.           the following.
  806.  
  807.           /* Before testing begins, make sure we are cable correctly. */
  808.           if ( !wyse_terminal(com)) {
  809.               AvidLogInfo(AVID, com, "Bad connection to Wyse terminal",    
  810.                                            BAD_CONNECTION, &add_info, "");
  811.           }
  812.  
  813.           Since the automation routine 'wyse_terminal' is of general use,
  814.           it could be put in a function library with other automation
  815.           routines written for wyse terminals.  The library could then be
  816.           distributed to other members of the programming staff.  Creating
  817.           general use automation routines allows automation programs to be
  818.           written like regular programs using a modular design.
  819.  
  820.           The following routine is an improvement on the 'wyse_terminal'
  821.           routine.  It will return a constant that specifies the type of
  822.           wyse that is connected.
  823.  
  824.  
  825.  
  826.                                                                          21
  827.  
  828.           /****************/
  829.           int terminal_type(com)
  830.           int com;
  831.           /****************/
  832.           {
  833.           char temp_s[85];
  834.           int err;
  835.           int add_info;
  836.  
  837.               /*
  838.                  Test to see if connected to a Wyse terminal.
  839.                  Use the command  ESC<space>
  840.                  Where:
  841.                  <space> is a blank space.
  842.  
  843.                  The Wyse terminal will return 30\r, 50\r, or 60\r
  844.               */
  845.  
  846.               sprintf(temp_s, "%s ", ESC_CODE);
  847.               AvidRegisterSend(AVID, com, temp_s, &add_info, "");
  848.  
  849.               AvidRegisterWait(AVID, com, WYSE_30, "30", &add_info, "");
  850.               AvidRegisterWait(AVID, com, WYSE_50, "50", &add_info, "");
  851.               AvidRegisterWait(AVID, com, WYSE_60, "60", &add_info, "");
  852.  
  853.               return(AvidSendSearch(AVID, com, (long)2, (long)5,
  854.                                                 &add_info, ".d'1'.D'3'"));
  855.           }
  856.  
  857.           Other parts of the program would then be able to make calls like
  858.           the following.
  859.  
  860.           /* Before testing Wyse 50 features, make sure this is a Wyse 50.
  861.           */
  862.           if ( terminal_type(com) != WYSE_50)
  863.               return;
  864.  
  865.           Notice that the 'terminal_type' routine uses AvidRegisterSend and
  866.           AvidRegisterWait to build the send-list and wait-list.  This is a
  867.           nice way to code this routine because of the constants WYSE_30,
  868.           WYSE_50, and WYSE_60.  These constants would be defined in a
  869.           global header file and can be given any valid values.  If
  870.           switches were used like in previous examples, WYSE_30 would have
  871.           to be defined as 1, WYSE_50 as 2, and WYSE_60 as 3.  It is best
  872.           that the 'terminal_type' routine not be required to match the
  873.           constant definitions.
  874.  
  875.  
  876.  
  877.                                                                          22
  878.  
  879.           The call to AvidSendSearch uses the .d'1' and .D'3' switches to
  880.           drain the communication port.  An explicit call to AvidDrainPort
  881.           would have yielded the same result.
  882.  
  883.           The above implementation of 'terminal_type' is a very good way to
  884.           code this automation routine.  However, I would like to code it a
  885.           different way to demonstrate AvidSendSearch's ability to capture
  886.           strings.  By adding the switch -c'2' and the parameters 'actual'
  887.           and 'captured' to AvidSendSearch, a string capture is possible,
  888.           as the following code segment will show.
  889.  
  890.           /****************/
  891.           int terminal_type(com)
  892.           int com;
  893.           /****************/
  894.           {
  895.           char temp_s[85];
  896.           int err, add_info;
  897.           char captured[50];
  898.           long actual;
  899.  
  900.               /*
  901.                  Test to see if connected to a Wyse terminal.
  902.                  Use the command  ESC<space>
  903.                  Where:
  904.                  <space> is a blank space.
  905.  
  906.                  The Wyse terminal will return 30\r, 50\r, or 60\r
  907.               */
  908.  
  909.               sprintf(temp_s, ".s'%s ' 1w'\r' .d'1' .D'3' -c'2'",          
  910.                                                                ESC_CODE);
  911.               if ((err = AvidSendSearch(AVID, com,
  912.                                    (long)2, (long)5, &add_info, temp_s,
  913.                                    (long *)&actual, captured)) <= ERR_SNF)
  914.                   return(err);
  915.  
  916.               return(atoi(captured));
  917.           }
  918.  
  919.           The -c'2' switch causes two characters to be captured.  After the
  920.           Wyse 50 receives the "ESC<space>" command, it returns 3
  921.           characters.  First, the character is '5', then '0', and then the
  922.           return character '\r'.  The capture string starts out empty, then
  923.           fills up during the automation sequence.  The following list
  924.           shows how the capture string fills.
  925.  
  926.  
  927.  
  928.                                                                          23
  929.  
  930.                     ""        - String empty.
  931.                     "5"       - First character received.
  932.                     "50"      - Next character received.
  933.                     "50"      - The return character received.
  934.  
  935.           When the return character is received, the automation sequence
  936.           stops.  Notice that the wait string ("\r" here) is not part of
  937.           the captured string.
  938.  
  939.           Suppose the Wyse 50 responds to the "ESC<space>" command
  940.           differently.  Instead of "50\r", say the Wyse 50 terminal
  941.           returned "Wyse50\r".  The code above will still work by capturing
  942.           only the string "50".  However, the capture string will fill up
  943.           differently as shown below.
  944.  
  945.                     ""        - String empty.
  946.                     "W"       - First character received.
  947.                     "Wy"      - Next character received.
  948.                     "ys"      - Next one.
  949.                     "se"      - Next one.
  950.                     "e5"      - Next one.
  951.                     "50"      - Next one.
  952.                     "50"      - The return character received.
  953.  
  954.           This illustrates how the capture will start ignoring characters
  955.           by letting them drop off of the end.
  956.  
  957.           The actual number of characters in the capture string may be less
  958.           than the amount specified in the switch.  This happens when the
  959.           automation sequence ends before the capture string is filled. 
  960.           Also, since NULL characters can be part of the input stream, the
  961.           actual number of characters in the captured string is passed back
  962.           to you in the parameter 'actual'.  Strlen(captured) may not equal
  963.           the actual number of characters in the captured string due the
  964.           NULL characters.
  965.  
  966.           There are actually two types of string captures possible from
  967.           AvidSendSearch.  The above sample code demonstrated the first
  968.           type, which is initiated with the switch -c'x', where x is the
  969.           maximum number of characters to capture.  The second type of
  970.           capture is invoked with the +c'x' switch, where x, again, is the
  971.           number of characters to capture.  However, there is a big
  972.           difference between these two types of captures.  The first type
  973.           (-c'x') starts pushing the oldest characters out of the capture
  974.           string after x characters have been received.  The second type of
  975.           capture (+c'x'), on the other hand, stops the automation sequence
  976.           when the capture string is full.
  977.  
  978.  
  979.  
  980.                                                                          24
  981.  
  982.           Before demonstrating the +c'x' capture, a little history.  When I
  983.           first wrote the AutoLibrary(tm) Program-Playback tool,
  984.           AvidSendSearch did not support capturing strings.  Instead, the
  985.           only way to get captured strings were to extract them from a hold
  986.           area with the routine AvidGetFromHoldArea.  Using
  987.           AvidGetFromHoldArea is still a valid way to get capture strings,
  988.           which the following code segment will show.  You will notice this
  989.           code segment gives the same results as the code segment above
  990.           that uses the -c'2' switch.
  991.  
  992.           /****************/
  993.           int terminal_type(com)
  994.           int com;
  995.           /****************/
  996.           {
  997.           char temp_s[85];
  998.           int err, add_info;
  999.           char captured[50];
  1000.           long actual;
  1001.  
  1002.               /*
  1003.                  Test to see if connected to a Wyse terminal.
  1004.                  Use the command  ESC<space>
  1005.                  Where:
  1006.                  <space> is a blank space.
  1007.  
  1008.                  The Wyse terminal will return 30\r, 50\r, or 60\r
  1009.               */
  1010.  
  1011.               sprintf(temp_s, ".s'%s ' 1w'\r' .d'1' .D'3'", ESC_CODE);
  1012.               if ((err = AvidSendSearch(AVID, com, (long)2, (long)5,
  1013.                                           &add_info, temp_s)) <= ERR_SNF)
  1014.                   return(err);
  1015.  
  1016.               actual = AvidGetFromHoldArea(AVID, com, 1, 2,
  1017.                                                 captured, &add_info, "");
  1018.  
  1019.               return(atoi(captured));
  1020.           }
  1021.  
  1022.           You will find AvidGetFromHoldArea useful in your automation
  1023.           routines because of its ability to extract from anywhere in the
  1024.           hold area and be able to span across data that was received from
  1025.           multiple automation sequences.  AvidGetFromHoldArea is a general
  1026.           utility for extracting capture strings.  However, I found that
  1027.           for the vast majority of strings that I wanted to capture,
  1028.           convenience was more important.  Therefore, I added the capture
  1029.           switch to AvidSendSearch.  Internally, AvidSendSearch calls
  1030.           AvidGetFromHoldArea with the correct parameters.  This process of
  1031.  
  1032.  
  1033.  
  1034.                                                                          25
  1035.  
  1036.           capturing strings seemed very natural to me.  The process where
  1037.           AvidSendSearch does not worry about the capture string until the
  1038.           automation sequence is over.  Then it looks backwards into the
  1039.           hold area to extract out the capture string.  This method of
  1040.           looking backwards into the hold area led naturally to the second
  1041.           type of capture.  Namely, a forward looking capture.  One that
  1042.           would start putting characters into the capture string as they
  1043.           were received from the communication port.  One where
  1044.           AvidSendSearch worries about the capture string before the
  1045.           automation sequence starts.
  1046.  
  1047.           The forward looking capture is invoked with the switch +c'x'. 
  1048.           This type of capture will be referred to as a Positive Capture. 
  1049.           The backward looking capture is invoked with the switch -c'x' and
  1050.           is referred to as a Negative Capture.  Just remember the minus
  1051.           sign '-' as the Negative Capture and the plus character '+' as
  1052.           the Positive Capture.  Also, remember that the Negative Capture
  1053.           looks backwards into the hold area after the automation sequence
  1054.           has finished.  Where as, the Positive Capture looks forward and
  1055.           builds the capture string as the automation sequence is
  1056.           occurring.  The Positive Capture will terminate the automation
  1057.           sequence if the capture string is full.  The Negative Capture
  1058.           will never end the automation sequence.
  1059.  
  1060.           It is useful to again code the Wyse 50's host identification
  1061.           command "ESC<space>" using a Positive Capture.
  1062.  
  1063.  
  1064.  
  1065.                                                                          26
  1066.  
  1067.           /****************/
  1068.           int terminal_type(com)
  1069.           int com;
  1070.           /****************/
  1071.           {
  1072.           char temp_s[85];
  1073.           int err, add_info;
  1074.           char captured[50];
  1075.           long actual;
  1076.  
  1077.               /*
  1078.                  Test to see if connected to a Wyse terminal.
  1079.                  Use the command  ESC<space>
  1080.                  Where:
  1081.                  <space> is a blank space.
  1082.  
  1083.                  The Wyse terminal will return 30\r, 50\r, or 60\r
  1084.               */
  1085.  
  1086.               sprintf(temp_s, ".s'%s ' .d'1' .D'3' +c'2'", ESC_CODE);
  1087.               if ((err = AvidSendSearch(AVID, com,
  1088.                                     (long)2, (long)5, &add_info, temp_s,   
  1089.                                  (long *)&actual, captured)) <= ERR_SNF)
  1090.                   return(err);
  1091.  
  1092.               return(atoi(captured));
  1093.           }
  1094.  
  1095.           The +c'2' switch specifies a Positive Capture of two characters. 
  1096.           The following list shows how the capture string is filled.
  1097.  
  1098.                     ""        - String empty.
  1099.                     "5"       - First character received.
  1100.                     "50"      - Next one.
  1101.                     "50"      - The automation sequence ends because the
  1102.                               capture string is full.
  1103.                               - The drain switches .d'1' and .D'3' will
  1104.                               drain the '\r' character.
  1105.  
  1106.           Suppose, as we did with the Negative Capture, that the Wyse 50
  1107.           returned "Wyse50\r" instead of "50\r".  Remember the examples
  1108.           showed the resulting capture string was "50" regardless of
  1109.           whether the Wyse 50 returned "Wyse50\r" or "50\r".  The result is
  1110.           different, however, for Positive Captures, as the following list
  1111.           will show.
  1112.  
  1113.  
  1114.  
  1115.                                                                          27
  1116.  
  1117.                     ""        - String empty.
  1118.                     "W"       - First character received.
  1119.                     "Wy"      - Next character received.
  1120.                     "Wy"      - The automation sequence ends with this as
  1121.                               the capture string. - The drain switches then
  1122.                               drain the characters "se50\r" (Not what is
  1123.                               desired).
  1124.  
  1125.           As you can see the result is not what was desired.  However,
  1126.           since we know the Wyse 50 really will return "50\r", both capture
  1127.           methods work fine.
  1128.  
  1129.           Again, suppose the Wyse 50 worked yet another way, where say, all
  1130.           terminal made before 1983 returned "Wyse50\r" and all terminals
  1131.           made after 1983 returned "50\r".  To make our automation routine
  1132.           work with both types of Wyse 50 terminals, the routine that uses
  1133.           the Negative Capture would be the only correct solution.
  1134.  
  1135.           I would like to describe the Positive Capture again with a better
  1136.           suited example.  The previous examples were good, however, they
  1137.           compared the Positive Capture with the Negative Capture in a
  1138.           situation where the Negative Capture was the best choice.  Now I
  1139.           would like to describe an example that is better suited for a
  1140.           Positive Capture.
  1141.  
  1142.           One place where the Positive Capture is best suited, is when the
  1143.           string to key off of is before the information to be captured. 
  1144.           Before describing a new example, the Reference Manual does have a
  1145.           good example for Positive Captures, which captures information
  1146.           about the current whether conditions.  In this example, the
  1147.           string "Temperature" is always displayed before the current
  1148.           temperature.  First, a call is made to AvidSendSearch that waits
  1149.           for the string "Temperature", then another AvidSendSearch call is
  1150.           made to actually capture the temperature.  A complete description
  1151.           of this example can be found in the reference guide in the
  1152.           section that describes AvidSendSearch.
  1153.  
  1154.           Another place where the Positive Capture is best suited is when
  1155.           the number of characters to capture needs to have an upper limit. 
  1156.           The following code captures the next 80 characters of an input
  1157.           stream.
  1158.  
  1159.           AvidSendSearch(AVID, com,
  1160.                        (long)10, (long)60, &add_info,
  1161.                        "+c'80' 1w'\r' 2w'\n'", (long *)&actual, captured);
  1162.  
  1163.           This piece of code would be used for reading in a "line" of data
  1164.           much like a line of data would be read from a file.  When 80
  1165.           characters have been received, AvidSendSearch will return with
  1166.  
  1167.  
  1168.  
  1169.                                                                          28
  1170.  
  1171.           the 80 characters in the capture string and the automation
  1172.           sequence would be finished.  If, however, a newline character
  1173.           ('\n') or a return character ('\r') is received, AvidSendSearch
  1174.           would return with less than 80 characters in the capture string.
  1175.  
  1176.           Notice there were no send strings.  It is ok (and common) for
  1177.           AvidSendSearch to be called without a send string.  For
  1178.           instances, a previous call to AvidSendSearch may have already
  1179.           started an input stream.  It is also possible, depending on the
  1180.           type of application or device that is being automated, that an
  1181.           input stream does not need initiated, i.e., characters will be
  1182.           coming in as soon as the port is opened.
  1183.  
  1184.           The following code segment adds to the previous one.  Here,
  1185.           AvidSendSearch is put in a while loop.  AvidSend is used to send
  1186.           the command that starts the data flowing.
  1187.  
  1188.           AvidSend(AVID, com, "facts\r", &add_info, "");
  1189.  
  1190.           while (( err = AvidSendSearch(AVID, com,
  1191.                              (long)10, (long)60, &add_info,
  1192.                              "+c'80' 1w'\r' 2w'\n'",
  1193.                              (long *)&actual, captured)) >= ERR_SNF) {
  1194.  
  1195.               /* It is ok for err to equal ERR_SNF if caused by capture    
  1196.              string filling up. */
  1197.               if ((err == ERR_SNF) && (add_info != ERR_CAPTURE_FULL))
  1198.                       break;
  1199.  
  1200.               /* Write captured string to a file. */
  1201.               fprintf(cap_file, "%s\n", captured);
  1202.           }
  1203.  
  1204.           Notice that AvidSend was used to send the command 'facts' to the
  1205.           host computer.  AvidSendSearch could have been used, with
  1206.           "facts\r" registered in the send-list and nothing registered in
  1207.           the wait-list.  However, AvidSend is a better choice here. 
  1208.           AvidSendSearch would have been a better choice if any of the
  1209.           other AvidSendSearch features were needed, such as, draining the
  1210.           communication port.
  1211.  
  1212.           This is the first example that uses 'add_info'.  'Add_info' is a
  1213.           return parameter that allows your automation programs to get more
  1214.           information on why an error occurred.  This example needs to know
  1215.           why the ERR_SNF was returned.  If ERR_SNF was returned due to a
  1216.           timeout, 'add_info' will return with ERR_REPEAT_TIMEOUT or
  1217.           ERR_ENDING_TIMEOUT.
  1218.  
  1219.  
  1220.  
  1221.                                                                          29
  1222.  
  1223.           Notice the above example compares 'add_info' to ERR_CAPTURE_FULL.
  1224.           This is the best way to find out if the automation sequence
  1225.           should continue.  When ERR_SNF is returned due to the capture
  1226.           string being full, more characters are out there to capture.
  1227.  
  1228.           Now to summarize what we have looked at so far.  This tutorial
  1229.           has introduced you to the following routines.
  1230.  
  1231.                AvidDrainPort --- Drains a communication port.
  1232.  
  1233.                AvidGetFromHoldArea --- Gets a string from the hold area.
  1234.  
  1235.                AvidLogInfo --- Log messages to a log file.
  1236.  
  1237.                AvidRegisterSend --- Registers a string in the send-list.
  1238.  
  1239.                AvidRegisterWait --- Registers a string in the wait-list.
  1240.  
  1241.                AvidSend --- Sends a string.
  1242.  
  1243.           Here is a list of the routines that I would like to introduce
  1244.           now.
  1245.  
  1246.                AvidClosePort --- Closes an AutoLibrary port.
  1247.  
  1248.                AvidExitAutoLibrary --- Exit from AutoLibrary.
  1249.  
  1250.                AvidInitAutoLibrary --- Initializes AutoLibrary.
  1251.  
  1252.                AvidOpenPort --- Opens an AutoLibrary port.
  1253.  
  1254.                AvidVersion --- Displays the AutoLibrary version.
  1255.  
  1256.           The following example uses these routines to put it all together. 
  1257.           The example will call the routine 'terminal_type' to determine
  1258.           the type of terminal connected.  It will then print the answer to
  1259.           the screen.
  1260.  
  1261.  
  1262.  
  1263.                                                                          30
  1264.  
  1265.  
  1266.           #include <stdio.h>
  1267.           #include <stdlib.h>
  1268.  
  1269.           #include "al.h"
  1270.  
  1271.           /******/
  1272.           void main(argc, argv)
  1273.           /******/
  1274.           int argc;
  1275.           char *argv[];
  1276.           {
  1277.           int com;
  1278.           int add_info;
  1279.  
  1280.               /* Initial AutoLibrary. */
  1281.               AvidInitAutoLibrary(AVID, &add_info, "_B'3'");
  1282.  
  1283.               /* Open the communication port. */
  1284.               com = AvidOpenPort(AVID, "com1", &add_info,
  1285.                                               ".b'9600' .1 .8 .n +S -H");
  1286.  
  1287.               /* Display AutoLibrary version. */
  1288.               AvidVersion(AVID, &add_info, "");
  1289.  
  1290.               /* Display the type of Wyse Terminal that is out there. */
  1291.               if ((term_type = terminal_type(com)) = 0)
  1292.                   printf("Not connected to a Wyse 30, 50, or 60\n");
  1293.               else
  1294.                   printf("Connected to a Wyse %i terminal\n", term_type);
  1295.  
  1296.               /* Finished so close the com port. */
  1297.               AvidClosePort(AVID, com, &add_info, "");
  1298.  
  1299.               /* Finished so exit from AutoLibrary. */
  1300.               AvidExitAutoLibrary(AVID, &add_info, "");
  1301.           }
  1302.  
  1303.  
  1304.  
  1305.                                                                          31
  1306.  
  1307.           /****************/
  1308.           int terminal_type(com)
  1309.           int com;
  1310.           /****************/
  1311.           {
  1312.           char temp_s[85];
  1313.           int err, add_info;
  1314.           char captured[50];
  1315.           long actual;
  1316.  
  1317.               /*
  1318.                  Test to see if connected to a Wyse terminal.
  1319.                  Use the command  ESC<space>
  1320.                  Where:
  1321.                  <space> is a blank space.
  1322.  
  1323.                  The Wyse terminal will return 30\r, 50\r, or 60\r
  1324.               */
  1325.  
  1326.               sprintf(temp_s, ".s'%s ' 1w'\r' .d'1' .D'3' -c'2'",          
  1327.                                                       ESC_CODE);
  1328.               if ((err = AvidSendSearch(AVID, com,
  1329.                                   (long)2, (long)5, &add_info, temp_s,
  1330.                                   (long *)&actual, captured)) <= ERR_SNF)
  1331.                   return(err);
  1332.  
  1333.               return(atoi(captured));
  1334.           }
  1335.  
  1336.           Now all of the routines in the AutoLibrary(tm) Program-Playback
  1337.           tool have been introduced in this tutorial except for the
  1338.           following.
  1339.  
  1340.                AvidConvert --- Utility routine that converts characters to
  1341.                strings.
  1342.  
  1343.                AvidLogOpen --- Open a log file for AvidLogInfo to use.
  1344.  
  1345.                AvidProcessOptions --- Used to process the options
  1346.                parameter.
  1347.  
  1348.                AvidRead --- Reads one character.
  1349.  
  1350.           AvidConvert and AvidProcessOptions are utility routines that your
  1351.           automation programs may use.  AvidConvert converts characters
  1352.           into strings.  When a character is not printable, AvidConvert
  1353.           will change it to a printable string.  AvidProcessOptions is the
  1354.           routine that is used internally to process the option parameter. 
  1355.           Your programs can use this routine if you also want to support an
  1356.  
  1357.  
  1358.  
  1359.                                                                          32
  1360.  
  1361.           options parameter.  AvidLogOpen opens a log file for AvidLogInfo
  1362.           to use.
  1363.  
  1364.           AvidRead is used internally by AvidDrainPort and AvidSendSearch. 
  1365.           Your automation programs should not require this routine.  It was
  1366.           included only for completeness.  The Reference Guide has a more
  1367.           information on these routines.
  1368.  
  1369.           This concludes the tutorial of the AutoLibrary(tm) Program-
  1370.           Playback tool.  I hope this section has given you a feel for how
  1371.           automation is done using this tool.
  1372.  
  1373.  
  1374.  
  1375.                                                                          33
  1376.  
  1377.  
  1378.           Reference Guide For the AutoLibrary(tm) Program-Playback tool
  1379.  
  1380.           The following is the reference guide for the AutoLibrary(tm)
  1381.           Program-Playback tool.  Each routine is described along with its
  1382.           parameters and options.  Examples are supplied for each routine.
  1383.  
  1384.  
  1385.  
  1386.                                                                          34
  1387.  
  1388.  
  1389.           AvidClosePort - Close Communication Port
  1390.  
  1391.           err = AvidClosePort(AVID, com, (int *)&add_info, opts)
  1392.  
  1393.           Parameter Description
  1394.  
  1395.           int err;       -- Return code.
  1396.  
  1397.           AVID      -- System parameter that must always be specified.
  1398.  
  1399.           int com;  -- The communications port to close.
  1400.  
  1401.           int *add_info; -- Additional return information.
  1402.  
  1403.           char *opts;    -- This is the input parameter for options.
  1404.  
  1405.           Options
  1406.  
  1407.           NONE
  1408.  
  1409.           Return Codes
  1410.  
  1411.           ERR_OK              -- No error occurred.
  1412.  
  1413.           ERR_NOT_INITIALIZED -- This error is returned when
  1414.                               AvidInitAutoLibrary is not called before this
  1415.                               routine is called.
  1416.  
  1417.           ERR_COMM_PACKAGE    -- This error can occur when the
  1418.                               communication package cannot close the
  1419.                               communication port correctly.  When this
  1420.                               error occurs, the parameter 'add_info' will
  1421.                               contain the actual error returned by the
  1422.                               communication package.
  1423.  
  1424.           ERR_INVALID_PORT    -- This error can occur when the
  1425.                               communication port specified in the 'com'
  1426.                               parameter was not a valid opened port.
  1427.  
  1428.           Additional Information Return Codes
  1429.  
  1430.           ERR_OK         -- No error occurred.
  1431.  
  1432.           <system err>   -- When ERR_COMM_PACKAGE is returned, 'add_info'
  1433.                          contains the actual error returned by the
  1434.                          communication package.
  1435.  
  1436.  
  1437.                                                               AvidClosePort
  1438.  
  1439.  
  1440.  
  1441.                                                                          35
  1442.  
  1443.  
  1444.           Description
  1445.  
  1446.           This routine closes the communication port that was opened by
  1447.           AvidOpenPort.  All of the memory allocated by AvidOpenPort is
  1448.           freed.  This routine calls CommInterfaceClose so the
  1449.           communication port of the comm package can be closed.  This
  1450.           routine will close the log if one was opened by AvidLogOpen.
  1451.  
  1452.           Examples
  1453.  
  1454.           The following example assumes there will not be any problems
  1455.           closing the port.
  1456.  
  1457.           AvidClosePort(AVID, com, &add_info, "");
  1458.  
  1459.           The following example checks for problems when closing the port.
  1460.  
  1461.           if ((err = AvidClosePort(AVID, com, &add_info, "")) != ERR_OK)
  1462.               printf("Error = %d, Additional Info = %d\n", err, add_info);
  1463.  
  1464.           See Also
  1465.  
  1466.           AvidOpenPort, CommInterfaceClose
  1467.  
  1468.  
  1469.  
  1470.  
  1471.  
  1472.  
  1473.  
  1474.  
  1475.  
  1476.  
  1477.  
  1478.  
  1479.  
  1480.  
  1481.  
  1482.  
  1483.  
  1484.  
  1485.  
  1486.  
  1487.  
  1488.  
  1489.  
  1490.  
  1491.  
  1492.                                                               AvidClosePort
  1493.  
  1494.  
  1495.  
  1496.                                                                          36
  1497.  
  1498.  
  1499.           AvidConvert - Convert Characters to Strings
  1500.  
  1501.           err = AvidConvert(c, s, (int *)&add_info, opts)
  1502.  
  1503.           Parameter Description
  1504.  
  1505.           int err;       -- Return code.
  1506.  
  1507.           int c;         -- Character to be converted.
  1508.  
  1509.           char *s;       -- Returned string.
  1510.  
  1511.           int *add_info; -- Additional return information.
  1512.  
  1513.           char *opts;    -- This is the input parameter for options.
  1514.  
  1515.           Options
  1516.  
  1517.           NONE
  1518.  
  1519.           Return Codes
  1520.  
  1521.           ERR_OK         -- No error occurred.
  1522.  
  1523.           Additional Information Return Codes
  1524.  
  1525.           ERR_OK         -- No error occurred.
  1526.  
  1527.           Description
  1528.  
  1529.           This routine converts characters into strings.  Each of the non-
  1530.           printable characters are converted into a coded string.  For
  1531.           example, the character '\0' would return as "[NUL]".  This
  1532.           routine is useful in EveryChar, which was the main reason this
  1533.           routine was written.  The following lists how each of the non-
  1534.           printable characters are returned.
  1535.  
  1536.           0    - [NUL]
  1537.           1    - [SOH]
  1538.           2    - [STX]
  1539.           3    - [ETX]
  1540.           4    - [EOT]
  1541.           5    - [ENQ]
  1542.           6    - [ACK]
  1543.           7    - [BEL]
  1544.           8    - [BS]
  1545.  
  1546.  
  1547.                                                                 AvidConvert
  1548.  
  1549.  
  1550.  
  1551.                                                                          37
  1552.  
  1553.           9    - [HT]
  1554.           10   - [LF]
  1555.           11   - [VT]
  1556.           12   - [FF]
  1557.           13   - [CR]
  1558.           14   - [SO]
  1559.           15   - [SI]
  1560.           16   - [DLE]
  1561.           17   - [DC1]
  1562.           18   - [DC2]
  1563.           19   - [DC3]
  1564.           20   - [DC4]
  1565.           21   - [NAK]
  1566.           22   - [SYN]
  1567.           23   - [ETB]
  1568.           24   - [CAN]
  1569.           25   - [EM]
  1570.           26   - [SUB]
  1571.           27   - [ESC]
  1572.           28   - [FS]
  1573.           29   - [GS]
  1574.           30   - [RS]
  1575.           31   - [US]
  1576.  
  1577.           127  - [DEL]
  1578.  
  1579.           Examples
  1580.  
  1581.           The following code will print all characters received from the
  1582.           communication port in a tty like mode.
  1583.  
  1584.           /*****/
  1585.           void EveryChar(c)
  1586.           int c;
  1587.           /*****/
  1588.           {
  1589.           char s[20];
  1590.           int add_info;
  1591.  
  1592.                   AvidConvert(c, s, &add_info, "");
  1593.                   printf("%s", s);
  1594.           }
  1595.  
  1596.           See Also
  1597.  
  1598.           EveryChar
  1599.  
  1600.  
  1601.  
  1602.                                                                 AvidConvert
  1603.  
  1604.  
  1605.  
  1606.                                                                          38
  1607.  
  1608.  
  1609.           AvidDrainPort - Drain Communication Port
  1610.  
  1611.           err = AvidDrainPort(AVID, com, (long)r_drain, (long)e_drain,     
  1612.                                              (int *)&add_info, opts)
  1613.  
  1614.           Parameter Description
  1615.  
  1616.           int err;       -- Return code.
  1617.  
  1618.           AVID           -- System parameter that must always be specified.
  1619.  
  1620.           int com;       -- The communications port to drain.
  1621.  
  1622.           long r_drain;  -- The number of seconds to drain the
  1623.                          communication port.  The drain time will start
  1624.                          over after each character received.  (A repeating
  1625.                          drain)
  1626.  
  1627.                          The parameter constant AVID_NO_TIMEOUT will cause
  1628.                          AvidDrainPort to never stop draining due to a
  1629.                          repeating drain value.
  1630.  
  1631.                          NOTE: AvidDrainPort will drain forever if
  1632.                          AVID_NO_TIMEOUT is used for both 'r_drain' and
  1633.                          'e_drain'.
  1634.  
  1635.           long e_drain;  -- The number of seconds to drain the
  1636.                          communication port.  The drain time will NOT start
  1637.                          over after each character received.  (An ending
  1638.                          drain)
  1639.  
  1640.                          The parameter constant AVID_NO_TIMEOUT will cause
  1641.                          AvidDrainPort to never stop draining due to an
  1642.                          ending drain value.
  1643.  
  1644.                          NOTE: AvidDrainPort will drain forever if
  1645.                          AVID_NO_TIMEOUT is used for both 'r_drain' and
  1646.                          'e_drain'.
  1647.  
  1648.           int *add_info; -- Additional return information.
  1649.  
  1650.           char *opts;    -- This is the input parameter for options.
  1651.  
  1652.           Options
  1653.  
  1654.           NONE
  1655.  
  1656.  
  1657.                                                               AvidDrainPort
  1658.  
  1659.  
  1660.  
  1661.                                                                          39
  1662.  
  1663.  
  1664.           Return Codes
  1665.  
  1666.           ERR_OK              -- No error occurred.
  1667.  
  1668.           ERR_NOT_INITIALIZED -- This error is returned when
  1669.                               AvidInitAutoLibrary is not called before this
  1670.                               routine is called.
  1671.  
  1672.           ERR_COMM_PACKAGE    -- This error can occur when AvidDrainPort
  1673.                               reads from the communication port.  When this
  1674.                               error occurs, the parameter 'add_info' will
  1675.                               contain the actual error returned by the
  1676.                               communication package.
  1677.  
  1678.           ERR_INVALID_PORT    -- This error can occur when the
  1679.                               communication port specified in the 'com'
  1680.                               parameter was not a valid opened port.
  1681.  
  1682.           Additional Information Return Codes
  1683.  
  1684.           ERR_OK              -- No error occurred.
  1685.  
  1686.           <system err>        -- When ERR_COMM_PACKAGE is returned,
  1687.                               'add_info' contains the actual error returned
  1688.                               by the communication package.
  1689.  
  1690.           Description
  1691.  
  1692.           This routine drains a communication port.  The drain time can be
  1693.           specified as a repeating timeout or as an ending timeout.  This
  1694.           routine can be called out explicitly or it is possible to drain a
  1695.           communication line directly from AvidSendSearch by using
  1696.           switches.
  1697.  
  1698.           Examples
  1699.  
  1700.           The following example will drain the communication port until
  1701.           there is 2 seconds of communications silents.  If there is not
  1702.           communications silents for 2 seconds, the drain will stop after
  1703.           20 seconds.
  1704.  
  1705.           err = AvidDrainPort(AVID, com, (long)2, (long)20, &add_info, "");
  1706.  
  1707.           The following example will drain the communication port until
  1708.           there is 4 seconds of communications silents.  If there is never
  1709.           communications silents this call will never return.
  1710.  
  1711.  
  1712.                                                               AvidDrainPort
  1713.  
  1714.  
  1715.  
  1716.                                                                          40
  1717.  
  1718.  
  1719.           err = AvidDrainPort(AVID, com, (long)4, AVID_NO_TIMEOUT,         
  1720.                                                   &add_info, "");
  1721.  
  1722.           The following example will drain for 5 seconds paying no
  1723.           attention to the communication activity.
  1724.  
  1725.           err = AvidDrainPort(AVID, com, AVID_NO_TIMEOUT, (long)5,         
  1726.                                                   &add_info, "");
  1727.  
  1728.           See Also
  1729.  
  1730.           AvidSendSearch (Especially .D and .d switches)
  1731.  
  1732.  
  1733.  
  1734.  
  1735.  
  1736.  
  1737.  
  1738.  
  1739.  
  1740.  
  1741.  
  1742.  
  1743.  
  1744.  
  1745.  
  1746.  
  1747.  
  1748.  
  1749.  
  1750.  
  1751.  
  1752.  
  1753.  
  1754.  
  1755.  
  1756.  
  1757.  
  1758.  
  1759.  
  1760.  
  1761.  
  1762.  
  1763.  
  1764.  
  1765.  
  1766.  
  1767.                                                               AvidDrainPort
  1768.  
  1769.  
  1770.  
  1771.                                                                          41
  1772.  
  1773.  
  1774.           AvidExitAutoLibrary - Exit AutoLibrary
  1775.  
  1776.           err = AvidExitAutoLibrary(AVID, (int *)&add_info, opts)
  1777.  
  1778.           Parameter Description
  1779.  
  1780.           int err;       -- Return code.
  1781.  
  1782.           AVID           -- System parameter that must always be specified.
  1783.  
  1784.           int *add_info; -- Additional return information.
  1785.  
  1786.           char *opts;    -- This is the input parameter for options.
  1787.  
  1788.           Options
  1789.  
  1790.           NONE
  1791.  
  1792.           Return Codes
  1793.  
  1794.           ERR_OK              -- No error occurred.
  1795.  
  1796.           ERR_NOT_INITIALIZED -- This error is returned when
  1797.                               AvidInitAutoLibrary is not called before this
  1798.                               routine is called.
  1799.  
  1800.           ERR_CANNOT_EXIT     -- All of the AutoLibrary ports need to be
  1801.                               closed first with AvidClosePort.
  1802.  
  1803.           Additional Information Return Codes
  1804.  
  1805.           ERR_OK              -- No error occurred.
  1806.  
  1807.           Description
  1808.  
  1809.           This routine exits from the AutoLibrary(tm) Program-Playback
  1810.           tool.  All memory and resources used by this tool are returned. 
  1811.           Once AvidExitAutoLibrary is called, it is possible to call
  1812.           AvidInitAutoLibrary to again initialize the AutoLibrary(tm)
  1813.           Program-Playback tool.
  1814.  
  1815.           Examples
  1816.  
  1817.           The following call is made after the last opened port is closed
  1818.           by AvidClosePort.
  1819.  
  1820.  
  1821.  
  1822.                                                         AvidExitAutoLibrary
  1823.  
  1824.  
  1825.  
  1826.                                                                          42
  1827.  
  1828.           err = AvidExitAutoLibrary(AVID, &add_info, "");
  1829.  
  1830.           See Also
  1831.  
  1832.           AvidInitAutoLibrary
  1833.  
  1834.  
  1835.  
  1836.  
  1837.  
  1838.  
  1839.  
  1840.  
  1841.  
  1842.  
  1843.  
  1844.  
  1845.  
  1846.  
  1847.  
  1848.  
  1849.  
  1850.  
  1851.  
  1852.  
  1853.  
  1854.  
  1855.  
  1856.  
  1857.  
  1858.  
  1859.  
  1860.  
  1861.  
  1862.  
  1863.  
  1864.  
  1865.  
  1866.  
  1867.  
  1868.  
  1869.  
  1870.  
  1871.  
  1872.  
  1873.  
  1874.  
  1875.  
  1876.  
  1877.                                                         AvidExitAutoLibrary
  1878.  
  1879.  
  1880.  
  1881.                                                                          43
  1882.  
  1883.  
  1884.           AvidGetFromHoldArea - Get Characters from Hold Area
  1885.  
  1886.           actual = AvidGetFromHoldArea(AVID, com, (long)pos, (long)size,   
  1887.                                             s, (int *)&add_info, opts)
  1888.  
  1889.           Parameter Description
  1890.  
  1891.           long actual;   -- This is the actual number of characters in s. 
  1892.                          This may not match strlen(s) if null characters
  1893.                          were received from the hold area.
  1894.  
  1895.           AVID           -- System parameter that must always be specified.
  1896.  
  1897.           int com;       -- The AutoLibrary communications port.
  1898.  
  1899.           long pos;      -- This is the position in the hold area to start
  1900.                          getting characters that will make up the string
  1901.                          returned.
  1902.  
  1903.           long size;     -- This is the size of the string to get.
  1904.  
  1905.           char *s;       -- This is the string that was built by
  1906.                          AvidGetFromHoldArea.
  1907.  
  1908.           int *add_info; -- Additional return information.
  1909.  
  1910.           char *opts;    -- This is the input parameter for options.
  1911.  
  1912.           Options
  1913.  
  1914.           NONE
  1915.  
  1916.           Return Codes
  1917.  
  1918.           <actual>  -- Returns the number of characters in the string. 
  1919.                     Zero is returned when there is no characters in the
  1920.                     hold area or if erroneous values where passed to it. 
  1921.                     For example, negative seven for the position or a
  1922.                     position that is specified outside the hold area
  1923.                     boundaries.
  1924.  
  1925.           Additional Information Return Codes
  1926.  
  1927.           ERR_OK    -- No error occurred.
  1928.  
  1929.           Description
  1930.  
  1931.  
  1932.                                                         AvidGetFromHoldArea
  1933.  
  1934.  
  1935.  
  1936.                                                                          44
  1937.  
  1938.  
  1939.           This routine will get characters from the hold area.  It is also
  1940.           possible to capture characters directly from the AvidSendSearch
  1941.           routine by specifying switches.
  1942.  
  1943.           Examples
  1944.  
  1945.           The following example will get 5 characters from the hold area
  1946.           starting at position 3.  If the hold area had the characters
  1947.           "0123456789", 'capture' would have the string "34567".
  1948.  
  1949.           actual = AvidGetFromHoldArea(AVID, com, (long)3, (long)5,
  1950.                                                   capture, &add_info, "");
  1951.  
  1952.           After the following example executed 'capture' would have the
  1953.           string "12" given the same hold area as above.
  1954.  
  1955.           actual = AvidGetFromHoldArea(AVID, com, (long)8, (long)2,
  1956.                                                   capture, &add_info, "");
  1957.  
  1958.           See Also
  1959.  
  1960.           AvidSendSearch (Especially +c and -c switches)
  1961.  
  1962.  
  1963.  
  1964.  
  1965.  
  1966.  
  1967.  
  1968.  
  1969.  
  1970.  
  1971.  
  1972.  
  1973.  
  1974.  
  1975.  
  1976.  
  1977.  
  1978.  
  1979.  
  1980.  
  1981.  
  1982.  
  1983.  
  1984.  
  1985.  
  1986.  
  1987.                                                         AvidGetFromHoldArea
  1988.  
  1989.  
  1990.  
  1991.                                                                          45
  1992.  
  1993.  
  1994.           AvidInitAutoLibrary - Initialize AutoLibrary
  1995.  
  1996.           err = AvidInitAutoLibrary(AVID, (int *)&add_info, opts)
  1997.  
  1998.           Parameter Description
  1999.  
  2000.           int err;       -- Return code.
  2001.  
  2002.           AVID           -- System parameter that must always be specified.
  2003.  
  2004.           int *add_info; -- Additional return information.
  2005.  
  2006.           char *opts;    -- This is the input parameter for options.
  2007.  
  2008.           Options
  2009.  
  2010.           _b'num'   -- This changes the number of milliseconds to delay
  2011.                     before sending the first character of the string.  The
  2012.                     specified value will replace the default permanently.
  2013.                     (Default is 0).
  2014.  
  2015.           _B'num'   -- This changes the number of milliseconds to delay
  2016.                     between each character sent.  The specified value will
  2017.                     replace the default permanently. (Default is 0).
  2018.  
  2019.           +h'num'   -- This option changes the size of the hold area.  This
  2020.                     value will automatically be increased if the chosen
  2021.                     value is less than AvidSendSearch's capture size
  2022.                     (SEND_SEARCH_CAPTURE_MAX).  (Default is 512).
  2023.  
  2024.           +R        -- This switch is used after your copy of AutoLibrary
  2025.                     is registered.  This will initialize AutoLibrary
  2026.                     without printing "Unregistered Evaluation Copy" to the
  2027.                     screen.
  2028.  
  2029.                     Unregistered users are not allowed to use this switch. 
  2030.                     However, if the actual printing of "Unregistered
  2031.                     Evaluation Copy" interferes with your ability to
  2032.                     evaluate AutoLibrary, you may temporarily use this
  2033.                     switch.
  2034.  
  2035.                     Note: The +R switch does not change the functionality
  2036.                     of AutoLibrary.  Both the registered and unregistered
  2037.                     initialization methods result in fully functional
  2038.                     software.
  2039.  
  2040.  
  2041.  
  2042.                                                         AvidInitAutoLibrary
  2043.  
  2044.  
  2045.  
  2046.                                                                          46
  2047.  
  2048.           Return Codes
  2049.  
  2050.           ERR_OK                   -- No error occurred.
  2051.  
  2052.           ERR_ALREADY_INITIALIZED  -- This routine cannot be called more
  2053.                                    than once without first call
  2054.                                    AvidExitAutoLibrary.
  2055.  
  2056.           Additional Information Return Codes
  2057.  
  2058.           ERR_OK    -- No error occurred.
  2059.  
  2060.           Description
  2061.  
  2062.           This routine is used to initialize the AutoLibrary(tm) Program-
  2063.           Playback tool.  This routine must be the first routine called. 
  2064.           Use AvidExitAutoLibrary to uninitialize.
  2065.  
  2066.           Examples
  2067.  
  2068.           The following example initializes AutoLibrary for the
  2069.           unregistered libraries.  (The unregistered libraries will print
  2070.           the message "Unregistered Evaluation Copy".
  2071.  
  2072.           err = AvidInitAutoLibrary(AVID, &add_info, "");
  2073.  
  2074.           The following example initialize AutoLibrary for the registered
  2075.           libraries.  The +R switch causes the printf to not occur.
  2076.  
  2077.           err = AvidInitAutoLibrary(AVID, &add_info,"+R");
  2078.  
  2079.           See Also
  2080.  
  2081.           AvidExitAutoLibrary
  2082.  
  2083.  
  2084.  
  2085.  
  2086.  
  2087.  
  2088.  
  2089.  
  2090.  
  2091.  
  2092.  
  2093.  
  2094.  
  2095.  
  2096.  
  2097.                                                         AvidInitAutoLibrary
  2098.  
  2099.  
  2100.  
  2101.                                                                          47
  2102.  
  2103.  
  2104.           AvidLogInfo - Log information to file or screen.
  2105.  
  2106.           val = AvidLogInfo(AVID, com, title, user_code,
  2107.                                                   (int *)&add_info, opts)
  2108.  
  2109.           Parameter Description
  2110.  
  2111.           int val;       -- Return code or if *E switch is specified, the
  2112.                          number of logged errors is returned.
  2113.  
  2114.           AVID           -- System parameter that must always be specified.
  2115.  
  2116.           int com;       -- The AutoLibrary communication port.
  2117.  
  2118.           char *title;   -- A one line string to log.
  2119.  
  2120.           int user_code; -- An integer value that can be used in any way to
  2121.                          add information to the log entry.
  2122.  
  2123.           int *add_info; -- Additional return information.
  2124.  
  2125.           char *opts;    -- This is the input parameter for options.
  2126.  
  2127.           Options
  2128.  
  2129.           +p   -- Print the log message to the screen using printf.  This
  2130.                switch guarantees the message will be printed, regardless of
  2131.                the current default.  The default is to print, but this can
  2132.                be changed by AvidLogOpen.
  2133.  
  2134.           -p   -- Do not print the message to the screen.  This switch
  2135.                guarantees the message will not be printed, regardless of
  2136.                the current default.  The default is to print, but this can
  2137.                be changed by AvidLogOpen.
  2138.  
  2139.           +E   -- After the error has been logged, 'exit(1)' is called to
  2140.                abort further processing.  This switch guarantees processing
  2141.                will abort, regardless of the current default.  The default
  2142.                is to continue processing, but this can be changed by
  2143.                AvidLogOpen.  This switch will only have effect on error
  2144.                messages, i.e., messages that use the *E switch.
  2145.  
  2146.           -E   -- After message has been logged, continue processing.  This
  2147.                switch guarantees processing will continue, regardless of
  2148.                the current default.  The default is to continue processing,
  2149.                but this can be changed by AvidLogOpen.
  2150.  
  2151.  
  2152.                                                                 AvidLogInfo
  2153.  
  2154.  
  2155.  
  2156.                                                                          48
  2157.  
  2158.  
  2159.           +L   -- Log the message to the log file.  This switch guarantees
  2160.                the message will be logged, regardless of the current
  2161.                default.  The default is to log all messages, but this can
  2162.                be changed by AvidLogOpen.  Also, this switch is only valid
  2163.                after AvidLogOpen is called to open the log file.
  2164.  
  2165.           -L   -- Do not log message in the log file.  This switch
  2166.                guarantees the message will not be logged, regardless of the
  2167.                current default.  The default is to log all messages, but
  2168.                this can be changed by AvidLogOpen.
  2169.  
  2170.           *E   -- This option directs AvidLogInfo to print the log entry as
  2171.                an error.  The string "ERROR(int)," is added to the log
  2172.                message.  AvidLogInfo returns the number of errors logged
  2173.                when this switch is specified.  The integer that is printed
  2174.                as part of ERROR(int) is the 'user_code' parameter.
  2175.  
  2176.           *T   -- This option directs AvidLogInfo to add a date and time
  2177.                stamp to the log entry.
  2178.  
  2179.           *L   -- This option directs AvidLogInfo to print information that
  2180.                identifies where AvidLogInfo was called from in your source
  2181.                code.  The line number and source file name will be added to
  2182.                the log message.  With this information, errors can be
  2183.                traced back to the exact source line they occurred.
  2184.  
  2185.           Return Codes
  2186.  
  2187.           <Positive Number>   -- The number of logged errors.  This is
  2188.                               possible only when the *E switch is used.
  2189.  
  2190.           ERR_OK              -- No error occurred.
  2191.  
  2192.           ERR_NOT_INITIALIZED -- This error is returned when
  2193.                               AvidInitAutoLibrary is not called before this
  2194.                               routine is called.
  2195.  
  2196.           ERR_WRITING         -- There was a problem writing to the log
  2197.                               file.
  2198.  
  2199.           ERR_INVALID_PORT    -- This error can occur when the
  2200.                               communication port specified in the 'com'
  2201.                               parameter was not a valid opened port.
  2202.  
  2203.           Additional Information Return Codes
  2204.  
  2205.  
  2206.  
  2207.                                                                 AvidLogInfo
  2208.  
  2209.  
  2210.  
  2211.                                                                          49
  2212.  
  2213.           ERR_OK              -- No error occurred.
  2214.  
  2215.           <system err>        -- When ERR_WRITING is returned, 'add_info'
  2216.                               will contain the system error that was
  2217.                               returned by the clib call to 'fprintf'.
  2218.  
  2219.           Description
  2220.  
  2221.           This routine makes it possible to log a message to a file, to the
  2222.           screen, or to both.  Switches are used to customize the format of
  2223.           a log message.  The examples below will show some of the ways
  2224.           this routine can be used.
  2225.  
  2226.           Examples
  2227.  
  2228.           The following example will use this routine to log when a test
  2229.           has started.  The 'user_code' is set to zero and is not used,
  2230.           since the *E switch was not specified.  The *T switch will add a
  2231.           time stamp to the logged message, which will document when the
  2232.           test started.  The output from this call is also shown.
  2233.  
  2234.           /* Log the type of test and when it started. */
  2235.           AvidLogInfo(AVID, com, "Executing screen location test",         
  2236.                                               0, &add_info, "*T");
  2237.  
  2238.           OUTPUT:
  2239.           Mon Jun 24 17:36:12 1991,Executing screen location test
  2240.  
  2241.           The following example will log an error.  Notice the error
  2242.           returned from AvidSendSearch is specified as the 'user_code'
  2243.           parameter.  This will help determine the cause of the error.  The
  2244.           switches *E, *T, and *L add more information to the error
  2245.           message.  The output from this call is also shown.
  2246.  
  2247.  
  2248.  
  2249.  
  2250.  
  2251.  
  2252.  
  2253.  
  2254.  
  2255.  
  2256.  
  2257.  
  2258.  
  2259.  
  2260.  
  2261.  
  2262.                                                                 AvidLogInfo
  2263.  
  2264.  
  2265.  
  2266.                                                                          50
  2267.  
  2268.           /* Make sure the cursor is where we placed it with ESC b */
  2269.           sprintf(temp_buf, ".s'%sb' 1w'C' -c'6'", ESC_CODE);
  2270.           if ((err = AvidSendSearch(AVID, com,
  2271.                               (long)10, (long)30, &add_info, temp_buf,
  2272.                               (long *)&actual, capture)) <= ERR_SNF) {
  2273.              num_logged = AvidLogInfo(AVID, com,
  2274.                             "Cursor not placed correctly",
  2275.                             err, &add_info, "*ETL");
  2276.           }
  2277.  
  2278.           OUTPUT:
  2279.           ERROR(-1002),Mon Jun 24 17:36:12 1991,(TST.C,74),Cursor not
  2280.           placed correctly
  2281.  
  2282.  
  2283.           The following example does not log the entry to the log file. 
  2284.           Instead, the message is printed to the screen.  The output from
  2285.           this call is also shown.
  2286.  
  2287.           /* Print Welcome message. */
  2288.           AvidLogInfo(AVID, com, "Welcome", 0, &add_info, "-L");
  2289.  
  2290.           OUTPUT:
  2291.           Welcome
  2292.  
  2293.           See Also
  2294.  
  2295.           AvidLogOpen
  2296.  
  2297.  
  2298.  
  2299.  
  2300.  
  2301.  
  2302.  
  2303.  
  2304.  
  2305.  
  2306.  
  2307.  
  2308.  
  2309.  
  2310.  
  2311.  
  2312.  
  2313.  
  2314.  
  2315.  
  2316.  
  2317.                                                                 AvidLogInfo
  2318.  
  2319.  
  2320.  
  2321.                                                                          51
  2322.  
  2323.  
  2324.           AvidLogOpen - Open a Log File.
  2325.  
  2326.           err = AvidLogOpen(AVID, com, filename, (int *)&add_info, opts)
  2327.  
  2328.           Parameter Description
  2329.  
  2330.           int err;            -- Return code.
  2331.  
  2332.           AVID                -- System parameter that must always be
  2333.                               specified.
  2334.  
  2335.           int com;            -- The AutoLibrary communication port.
  2336.  
  2337.           char *filename;     -- The file to open as a log file.
  2338.  
  2339.           int *add_info;      -- Additional return information.
  2340.  
  2341.           char *opts;         -- This is the input parameter for options.
  2342.  
  2343.           Options
  2344.  
  2345.           -p   -- This option changes the default for AvidLogInfo to not
  2346.                print the log message to the screen.  The normal default
  2347.                prints messages to the screen using 'printf'.
  2348.  
  2349.           +E   -- This option changes the default for AvidLogInfo to abort
  2350.                processing after the error has been logged.  The normal
  2351.                default continues processing after logging errors.  This
  2352.                switch will only have effect on error messages, i.e., those
  2353.                messages that use the *E switch.
  2354.  
  2355.           Return Codes
  2356.  
  2357.           ERR_OK              -- No error occurred.
  2358.  
  2359.           ERR_NOT_INITIALIZED -- This error is returned when
  2360.                               AvidInitAutoLibrary is not called before this
  2361.                               routine is called.
  2362.  
  2363.           ERR_OPENING         -- There was a problem opening the log file.
  2364.  
  2365.           ERR_INVALID_PORT    -- This error can occur when the
  2366.                               communication port specified in the 'com'
  2367.                               parameter was not a valid opened port.
  2368.  
  2369.           Additional Information Return Codes
  2370.  
  2371.  
  2372.                                                                 AvidLogOpen
  2373.  
  2374.  
  2375.  
  2376.                                                                          52
  2377.  
  2378.  
  2379.           ERR_OK              -- No error occurred.
  2380.  
  2381.           Description
  2382.  
  2383.           This routine is used to open a log file that AvidLogInfo will
  2384.           use.  The switches that this routine supports allows AvidLogInfo
  2385.           to have different defaults.  AvidLogOpen is needed only to open a
  2386.           log file and is not required before AvidLogInfo is called. 
  2387.           However, if AvidLogOpen is not called, AvidLogInfo is restricted
  2388.           to logging messages to the screen.
  2389.  
  2390.           Examples
  2391.  
  2392.           The following example will open a log file called "logfile".
  2393.  
  2394.           err = AvidLogOpen(AVID, com, "logfile", &add_info, "");
  2395.  
  2396.           The following example will again open a log file called
  2397.           "logfile".  However, it will also change the defaults for
  2398.           AvidLogInfo to not print log entries to the screen and to abort
  2399.           processing after logging error messages.
  2400.  
  2401.           err = AvidLogOpen(AVID, com, "logfile", &add_info, "-p +E");
  2402.  
  2403.           See Also
  2404.  
  2405.           AvidLogInfo
  2406.  
  2407.  
  2408.  
  2409.  
  2410.  
  2411.  
  2412.  
  2413.  
  2414.  
  2415.  
  2416.  
  2417.  
  2418.  
  2419.  
  2420.  
  2421.  
  2422.  
  2423.  
  2424.  
  2425.  
  2426.  
  2427.                                                                 AvidLogOpen
  2428.  
  2429.  
  2430.  
  2431.                                                                          53
  2432.  
  2433.  
  2434.           AvidOpenPort - Open Communication Port
  2435.  
  2436.           com = AvidOpenPort(AVID, device, (int *)&add_info, opts)
  2437.  
  2438.           Parameter Description
  2439.  
  2440.           int com;       -- This is the AutoLibrary port identification
  2441.                          number that is used by all of the AutoLibrary
  2442.                          routines.
  2443.  
  2444.           AVID           -- System parameter that must always be specified.
  2445.  
  2446.           char *device;  -- This is the device name of the communication
  2447.                          port to open.
  2448.  
  2449.           int *add_info; -- Additional return information.
  2450.  
  2451.           char *opts;    -- This is the input parameter for options.
  2452.  
  2453.           Options
  2454.  
  2455.           _b'num'   -- This changes the number of milliseconds to delay
  2456.                     before sending the first character of the string.  The
  2457.                     specified value will replace the default permanently
  2458.                     for this port.  (Default is 0).
  2459.  
  2460.           _B'num'   -- This changes the number of milliseconds to delay
  2461.                     between each character sent.  The specified value will
  2462.                     replace the default permanently for this port. (Default
  2463.                     is 0).
  2464.  
  2465.           +h'num'   -- This option changes the size of the hold area for
  2466.                     this port.  This value will automatically be increased
  2467.                     if the chosen value is less than AvidSendSearch's
  2468.                     capture size (SEND_SEARCH_CAPTURE_MAX).  (Default is
  2469.                     512).
  2470.  
  2471.           Options (Depends on implementation of CommInterfaceOpen)
  2472.  
  2473.           .b'baud'  -- This will change the baud rate from the default of
  2474.                     9600 to the specified value.  Choose from:  50, 75,
  2475.                     110, 134.5, 150, 300, 600, 1200, 1800, 2000, 2400,
  2476.                     3600, 4800, 7200, 9600, 19200. (Default is 9600).
  2477.  
  2478.           .1        -- One stop bit will be used. (Default).
  2479.  
  2480.  
  2481.  
  2482.                                                                AvidOpenPort
  2483.  
  2484.  
  2485.  
  2486.                                                                          54
  2487.  
  2488.           .2        -- Two stop bits will be used. (Default is 1).
  2489.  
  2490.           .7        -- Seven bits per word. (Default is 8).
  2491.  
  2492.           .8        -- Eight bits per word. (Default).
  2493.  
  2494.           .e        -- Even parity will be used. (Default is odd).
  2495.  
  2496.           .o        -- Odd parity will be used. (Default).
  2497.  
  2498.           .n        -- No parity will be used. (Default is odd).
  2499.  
  2500.           -S        -- This will cause the 7th bit to NOT be stripped.
  2501.                     (Default is to strip).
  2502.  
  2503.           +S        -- This will cause the 7th bit to be stripped.
  2504.                     (Default).
  2505.  
  2506.           +X        -- This will cause software (xon-xoff) flow control to
  2507.                     be used. (Default).
  2508.  
  2509.           -X        -- This will cause software (xon-xoff) flow control to
  2510.                     not be used. (Default is on).
  2511.  
  2512.           .T        -- This will cause dtr to be asserted. (Default is not
  2513.                     to).
  2514.  
  2515.           rx'num'   -- Changes the default receive buffer size. (Default is
  2516.                     8192).
  2517.  
  2518.           tx'num'   -- Changes the default transmit buffer size. (Default
  2519.                     is 512).
  2520.  
  2521.           The Greenleaf Comm Library
  2522.  
  2523.           This is a commerical communication package provided by Greenleaf
  2524.           Software, Inc.  16479 Dallas Parkway, Bent Tree Tower Two, Suite
  2525.           570, Dallas, TX  75248,  (214)248-2561.
  2526.  
  2527.           (Note: This is just one of many good communication packages.  It
  2528.           is easy to write interface routines for the AutoLibrary Program-
  2529.           Playback Tool, so don't feel you are tied to any one
  2530.           communication package.)
  2531.  
  2532.           Options Supported
  2533.  
  2534.  
  2535.  
  2536.  
  2537.                                                                AvidOpenPort
  2538.  
  2539.  
  2540.  
  2541.                                                                          55
  2542.  
  2543.           .b'num'  .1  .2  .7  .8  .e  .o  .n  -S  +S  +X  -X  .T  rx'num' 
  2544.           tx'num'
  2545.  
  2546.           Baud rates supported are:  50, 75, 110, 134.5, 150, 300, 600,
  2547.           1200, 1800, 2000, 2400, 3600, 4800, 7200, 9600, 19200. (Default
  2548.           is 9600).
  2549.  
  2550.           The ifsrtcl.lib Comm Library
  2551.  
  2552.           This is a basic communication package supplied with this product
  2553.           that combines the interface routines with asynchronous
  2554.           communication software.  It is intended to allow you to evaluate
  2555.           AutoLibrary and make it easy to get started.
  2556.  
  2557.           ERR_QUEUE_FULL is returned if the send queue is full. 
  2558.           ERR_INVALID_PORT is returned if something other than com1 or com2
  2559.           is specified.
  2560.  
  2561.           Options Supported
  2562.  
  2563.           .b'num' .1  .2  .7  .8  .e  .o  .n
  2564.  
  2565.           Baud rates supported are:  110, 150, 300, 600, 1200, 2400, 4800,
  2566.           9600. (Default is 9600).
  2567.  
  2568.           Also, the default is to use receive Xon/Xoff, and cannot be
  2569.           changed.  Transmit Xon/Xoff is not supported, i.e., this package
  2570.           will ignore Xoff characters.  However, the Xon/Xoff the protocol
  2571.           will be used if characters are received faster than they are
  2572.           processed.  The restriction works out ok because you can control
  2573.           how many characters you send but cannot control how many and how
  2574.           fast characters are received.
  2575.  
  2576.           Return Codes
  2577.  
  2578.           <Positive number>   -- No error occurred.  The positive number is
  2579.                               the AutoLibrary port number.
  2580.  
  2581.           ERR_NOT_INITIALIZED -- This error is returned when
  2582.                               AvidInitAutoLibrary is not called before this
  2583.                               routine is called.
  2584.  
  2585.           ERR_COMM_PACKAGE    -- This error can occur when the
  2586.                               communication package cannot open the
  2587.                               communication port correctly.  When this
  2588.                               error occurs, the parameter 'add_info' will
  2589.  
  2590.  
  2591.  
  2592.                                                                AvidOpenPort
  2593.  
  2594.  
  2595.  
  2596.                                                                          56
  2597.  
  2598.                               contain the actual error returned by the
  2599.                               communication package.
  2600.  
  2601.           ERR_EXCEEDED_COMLIST_SIZE     -- This will occur when an attempt
  2602.                                         is made to open more than
  2603.                                         COMLIST_SIZE.  The default for this
  2604.                                         value is 30, which can be changed
  2605.                                         by re-compiling AutoLibrary.
  2606.  
  2607.           ERR_NO_MEMORY       -- This will occur when there is no more
  2608.                               memory to allocate required data structures.
  2609.  
  2610.           Additional Information Return Codes
  2611.  
  2612.           ERR_OK              -- No error occurred.
  2613.  
  2614.           <system err>        -- When ERR_COMM_PACKAGE is returned,
  2615.                               'add_info' contains the actual error returned
  2616.                               by the communication package.
  2617.  
  2618.           Description
  2619.  
  2620.           This routine opens an AutoLibrary communication port.  This
  2621.           routine creates the required data structures to support
  2622.           automation and calls CommInterfaceOpen to open the hardware port
  2623.           of the communication package supplied.
  2624.  
  2625.           IMPORTANT:  Note: the list of options for this routine are
  2626.           dependent on how the interface library routine CommInterfaceOpen
  2627.           was implemented.  
  2628.  
  2629.           Examples
  2630.  
  2631.           The following example opens the communication port at 9600 baud,
  2632.           one stop bit, eight bits per word, no parity, strip 7th bit, and
  2633.           do not use hardware flow control.
  2634.  
  2635.           com = AvidOpenPort(AVID, "com1", &add_info,
  2636.                                               ".b'9600' .1 .8 .n +S -H");
  2637.  
  2638.           See Also
  2639.  
  2640.           AvidClosePort, CommInterfaceOpen
  2641.  
  2642.  
  2643.  
  2644.  
  2645.  
  2646.  
  2647.                                                                AvidOpenPort
  2648.  
  2649.  
  2650.  
  2651.                                                                          57
  2652.  
  2653.  
  2654.           AvidProcessOptions - Parse an Option Parameter List
  2655.  
  2656.           o_char = AvidProcessOptions(AVID, o_list, target,
  2657.                                    (char *)&control, arg_s, (int *)&start)
  2658.  
  2659.           Parameter Description
  2660.  
  2661.           char o_char;   -- This is the character part of the option.  This
  2662.                          will have a '\0' (null) value when there are no
  2663.                          more options to process.  If the switch was -
  2664.                          X'good', for example, 'o_char' would return 'X'.
  2665.  
  2666.           AVID           -- System parameter that must always be specified.
  2667.  
  2668.           char *o_list;  -- This is the list of options.
  2669.  
  2670.           char *target;  -- Look only for the option specified as the
  2671.                          target.  This makes it possible to scan for the
  2672.                          target option without using a while loop.
  2673.  
  2674.           char *control; -- This is the option control character of the
  2675.                          parsed option.  If the switch was -X'good', for
  2676.                          example, 'control' would return '-'.
  2677.  
  2678.           char *arg_s;   --  This is where the options argument is written. 
  2679.                          If the switch does not have an argument, a null
  2680.                          string is returned.  If the switch was -X'good',
  2681.                          for example, 'arg_s' would return "good".
  2682.  
  2683.           int *start;    -- The location to start parsing in the option
  2684.                          list.  This parameter must be initialized to zero,
  2685.                          then left alone.  It is used internally by
  2686.                          AvidProcessOptions to track which switch to return
  2687.                          next.
  2688.  
  2689.           Options
  2690.  
  2691.           NONE
  2692.  
  2693.           Return Codes
  2694.  
  2695.           Not applicable.
  2696.  
  2697.           Description
  2698.  
  2699.  
  2700.  
  2701.  
  2702.                                                          AvidProcessOptions
  2703.  
  2704.  
  2705.  
  2706.                                                                          58
  2707.  
  2708.           This is the routine that parses the option parameters that every
  2709.           AutoLibrary routine has.  AvidProcessOptions is not needed to
  2710.           support automation, however, it has been documented and made
  2711.           public because it is a nice routine of general utility.
  2712.  
  2713.  
  2714.  
  2715.  
  2716.  
  2717.  
  2718.  
  2719.  
  2720.  
  2721.  
  2722.  
  2723.  
  2724.  
  2725.  
  2726.  
  2727.  
  2728.  
  2729.  
  2730.  
  2731.  
  2732.  
  2733.  
  2734.  
  2735.  
  2736.  
  2737.  
  2738.  
  2739.  
  2740.  
  2741.  
  2742.  
  2743.  
  2744.  
  2745.  
  2746.  
  2747.  
  2748.  
  2749.  
  2750.  
  2751.  
  2752.  
  2753.  
  2754.  
  2755.  
  2756.  
  2757.                                                          AvidProcessOptions
  2758.  
  2759.  
  2760.  
  2761.                                                                          59
  2762.  
  2763.           Examples
  2764.  
  2765.           AvidProcessOptions can be used two ways.  This example shows the
  2766.           first way, where the 'target' parameter is given a specific
  2767.           switch to look for, namely, "-L".  AvidProcessOptions won't
  2768.           return until it finds this specific switch or it returns NULL. 
  2769.           This method eliminates the need to call AvidProcessOptions in a
  2770.           loop.
  2771.  
  2772.           /* Find out if over night tests should be done. */
  2773.           if (AvidProcessOptions(AVID, arg_str, "-L",
  2774.                                            &control, arg, &start) != '\0')
  2775.               long_version = TRUE;
  2776.           else
  2777.               long_version = FALSE;
  2778.  
  2779.           The second way to use AvidProcessOptions is to call it in a while
  2780.           loop.  The 'target' parameter is left empty, which tells
  2781.           AvidProcessOptions to return the next switch.  The 'sc' variable
  2782.           returns with the switch character and the 'control' variable
  2783.           returns with the control character.  It is important to
  2784.           initialize the 'start' parameter to zero, because this variable
  2785.           is used to determine which switch to return.  If, for example,
  2786.           the 'start' parameter was set to zero inside the while loop,
  2787.           AvidProcessOptions would always return the first switch.
  2788.  
  2789.           /* Find out what kind of batch mode testing to do. */
  2790.           start=0; /* Required by AvidProcessOptions. */
  2791.           while ((sc=AvidProcessOptions(AVID, arg_str, "",
  2792.                                         &control, arg, &start)) != '\0') {
  2793.  
  2794.               /* Execute print test if "+P" switch was specified. */
  2795.               if ((control == '+') && (sc == 'P')) {
  2796.                   initialize_testing(com);
  2797.                   test_scr_print(com, 20, 80);
  2798.               }
  2799.  
  2800.               /* Execute screen attributes test if "-a" switch was
  2801.                  specified. */
  2802.               if ((control == '-') && (sc == 'a')) {
  2803.                   initialize_testing(com);
  2804.                   test_scr_attribs(com);
  2805.               }
  2806.           }
  2807.  
  2808.  
  2809.  
  2810.  
  2811.  
  2812.                                                          AvidProcessOptions
  2813.  
  2814.  
  2815.  
  2816.                                                                          60
  2817.  
  2818.  
  2819.           AvidRead - Read a Character
  2820.  
  2821.           c = AvidRead(AVID, com, (long)r_timeout, (long)e_timeout,
  2822.                                                 (int *)&add_info, opts)
  2823.  
  2824.           Parameter Description
  2825.  
  2826.           int c;              -- The character received is returned.
  2827.  
  2828.           AVID                -- System parameter that must always be
  2829.                               specified.
  2830.  
  2831.           int com;            -- The AutoLibrary port number.
  2832.  
  2833.           long r_timeout;     -- The number of seconds to wait for a
  2834.                               character.  The timeout value starts over
  2835.                               after each character received.
  2836.  
  2837.           long e_timeout;     -- The total number of seconds wait for a
  2838.                               character plus the current number of seconds. 
  2839.                               The timeout value does NOT start over after
  2840.                               each character received.
  2841.  
  2842.                               AvidRead is different from the other
  2843.                               AutoLibrary routines that use an ending
  2844.                               timeout.  For AvidRead the current number of
  2845.                               seconds since Jan 1, 1970 must be added to
  2846.                               the delay before making the call.  Use the
  2847.                               following code segment.
  2848.  
  2849.                               time(seconds);
  2850.                               if (e_timeout != AVID_NO_TIMEOUT)
  2851.                                    e_timeout = e_timeout + seconds;
  2852.  
  2853.                               ( make call to AvidRead here )
  2854.  
  2855.           int *add_info;      -- Additional return information.
  2856.  
  2857.           char *opts;         -- This is the input parameter for options.
  2858.  
  2859.           Options
  2860.  
  2861.           NONE
  2862.  
  2863.           Return Codes
  2864.  
  2865.  
  2866.  
  2867.                                                                    AvidRead
  2868.  
  2869.  
  2870.  
  2871.                                                                          61
  2872.  
  2873.           <character>         -- No error occurred.
  2874.  
  2875.           ERR_NOT_INITIALIZED -- This error is returned when
  2876.                               AvidInitAutoLibrary is not called before this
  2877.                               routine is called.
  2878.  
  2879.           ERR_COMM_PACKAGE    -- This error can occur when the
  2880.                               communication package cannot read the
  2881.                               communication port correctly.  When this
  2882.                               error occurs, the parameter 'add_info' will
  2883.                               contain the actual error returned by the
  2884.                               communication package.
  2885.  
  2886.           ERR_EOF             -- There were no more characters to read or a
  2887.                               timeout occurred.  If a timeout occurred,
  2888.                               'add_info' will have the values
  2889.                               ERR_REPEAT_TIMEOUT or ERR_ENDING_TIMEOUT.
  2890.  
  2891.           ERR_INVALID_PORT    -- This error can occur when the
  2892.                               communication port specified in the 'com'
  2893.                               parameter was not a valid opened port.
  2894.  
  2895.           Additional Information Return Codes
  2896.  
  2897.           ERR_OK              -- No error occurred.
  2898.  
  2899.           <system err>        -- When ERR_COMM_PACKAGE is returned,
  2900.                               'add_info' will contain the actual error
  2901.                               returned by the communication package.
  2902.  
  2903.           ERR_REPEAT_TIMEOUT  -- When ERR_EOF is returned and the cause for
  2904.                               the timeout is a Repeating Timeout, this is
  2905.                               the value returned.
  2906.  
  2907.           ERR_ENDING_TIMEOUT  -- When ERR_EOF is returned and the cause is
  2908.                               an Ending Timeout, this is the value
  2909.                               returned.
  2910.  
  2911.           Description
  2912.  
  2913.           This routine will read one character at a time from the
  2914.           communication port.  This routine is supplied only for
  2915.           completeness and is not required for automation.  Internally
  2916.           AvidSendSearch and AvidDrainPort call this routine to read
  2917.           characters.  The ending timeout must be fixed up as described
  2918.           above in the parameter definition of 'e_timeout'.
  2919.  
  2920.  
  2921.  
  2922.                                                                    AvidRead
  2923.  
  2924.  
  2925.  
  2926.                                                                          62
  2927.  
  2928.           AvidSendSearch should be used to read characters into a buffer,
  2929.           instead of AvidRead.
  2930.  
  2931.           Examples
  2932.  
  2933.           See the source code for AvidSendSearch or AvidDrainPort.
  2934.  
  2935.           See Also
  2936.  
  2937.           CommInterfaceRead
  2938.  
  2939.  
  2940.  
  2941.  
  2942.  
  2943.  
  2944.  
  2945.  
  2946.  
  2947.  
  2948.  
  2949.  
  2950.  
  2951.  
  2952.  
  2953.  
  2954.  
  2955.  
  2956.  
  2957.  
  2958.  
  2959.  
  2960.  
  2961.  
  2962.  
  2963.  
  2964.  
  2965.  
  2966.  
  2967.  
  2968.  
  2969.  
  2970.  
  2971.  
  2972.  
  2973.  
  2974.  
  2975.  
  2976.  
  2977.                                                                    AvidRead
  2978.  
  2979.  
  2980.  
  2981.                                                                          63
  2982.  
  2983.  
  2984.           AvidRegisterSend - Register a String to Send
  2985.  
  2986.           err = AvidRegisterSend(AVID, com, s_string,
  2987.                                               (int *)&add_info, opts)
  2988.  
  2989.           Parameter Description
  2990.  
  2991.           int err;            -- Return code.
  2992.  
  2993.           AVID                -- System parameter that must always be
  2994.                               specified.
  2995.  
  2996.           int com;            -- The AutoLibrary port number.
  2997.  
  2998.           char *s_string;     -- This is the string to be sent by
  2999.                               AvidSendSearch.
  3000.  
  3001.           int *add_info;      -- Additional return information.
  3002.  
  3003.           char *opts;         -- This is the input parameter for options.
  3004.  
  3005.           Options
  3006.  
  3007.           _b'num'   -- This changes the number of milliseconds to delay
  3008.                     before sending the first character of the string.  The
  3009.                     specified value will replace the default only for this
  3010.                     invocation.  Use AvidInitAutoLibrary or AvidOpenPort to
  3011.                     change the defaults permanently. (Default is 0).
  3012.  
  3013.           _B'num'   -- This changes the number of milliseconds to delay
  3014.                     between each character sent.  The specified value will
  3015.                     replace the default only for this invocation.  Use
  3016.                     AvidInitAutoLibrary or AvidOpenPort to change the
  3017.                     defaults permanently. (Default is 0).
  3018.  
  3019.           .N'num'   -- This is the number of null characters in the string. 
  3020.                     For example, .N'3' would be specified for the string
  3021.                     "\n\r\0\0abc\0".
  3022.  
  3023.           Return Codes
  3024.  
  3025.           ERR_OK              -- No error occurred.
  3026.  
  3027.           ERR_NOT_INITIALIZED -- This error is returned when
  3028.                               AvidInitAutoLibrary is not called before this
  3029.                               routine is called.
  3030.  
  3031.  
  3032.                                                            AvidRegisterSend
  3033.  
  3034.  
  3035.  
  3036.                                                                          64
  3037.  
  3038.  
  3039.           ERR_NO_MEMORY       -- This error will occur when there is not
  3040.                               enough memory to allocate the required data
  3041.                               structures.
  3042.  
  3043.           ERR_INVALID_PORT    -- This error can occur when the
  3044.                               communication port specified in the 'com'
  3045.                               parameter was not a valid opened port.
  3046.  
  3047.           Additional Information Return Codes
  3048.  
  3049.           ERR_OK              -- No error occurred.
  3050.  
  3051.           Description
  3052.  
  3053.           This routine will register a string to be sent when
  3054.           AvidSendSearch is called.  AvidRegisterSend does not send the
  3055.           string, it puts it into a linked list.
  3056.  
  3057.           Note that calling AvidRegisterSend is optional since send strings
  3058.           can be registered directly from AvidSendSearch by using switches.
  3059.  
  3060.           Examples
  3061.  
  3062.           The following example registers the specified string for
  3063.           AvidSendSearch to send.
  3064.  
  3065.           err = AvidRegisterSend(AVID, com, "hi there\r", &add_info, "");
  3066.  
  3067.           See Also
  3068.  
  3069.           AvidRegisterWait, AvidSendSearch (Especially the .s switch)
  3070.  
  3071.  
  3072.  
  3073.  
  3074.  
  3075.  
  3076.  
  3077.  
  3078.  
  3079.  
  3080.  
  3081.  
  3082.  
  3083.  
  3084.  
  3085.  
  3086.  
  3087.                                                            AvidRegisterSend
  3088.  
  3089.  
  3090.  
  3091.                                                                          65
  3092.  
  3093.  
  3094.           AvidRegisterWait - Register a Wait String
  3095.  
  3096.           err = AvidRegisterWait(AVID, com, r_num, w_string,
  3097.                                                (int *)&add_info, opts)
  3098.  
  3099.           Parameter Description
  3100.  
  3101.           int err;            -- Return code.
  3102.  
  3103.           AVID                -- System parameter that must always be
  3104.                               specified.
  3105.  
  3106.           int com;            -- The AutoLibrary port number.
  3107.  
  3108.           int r_num;          -- This is the registered number to be
  3109.                               returned by AvidSendSearch if the string is
  3110.                               found.
  3111.  
  3112.                               Numbers from 20,000 to max integer are
  3113.                               reserved by Avid Software for future use and
  3114.                               internal implementations.
  3115.  
  3116.           char *w_string;     -- This is the string to add to the wait-
  3117.                               list.  If this string is found by
  3118.                               AvidSendSearch, the registered value will be
  3119.                               returned.
  3120.  
  3121.           int *add_info;      -- Additional return information.
  3122.  
  3123.           char *opts;         -- This is the input parameter for options.
  3124.  
  3125.           Options
  3126.  
  3127.           .N'num'   -- This is the number of null characters in the string. 
  3128.                     For example, .N'3' would be specified for the string
  3129.                     "\n\r\0\0abc\0".
  3130.  
  3131.           Return Codes
  3132.  
  3133.           ERR_OK              -- No error occurred.
  3134.  
  3135.           ERR_NOT_INITIALIZED -- This error is returned when
  3136.                               AvidInitAutoLibrary is not called before this
  3137.                               routine is called.
  3138.  
  3139.  
  3140.  
  3141.  
  3142.                                                            AvidRegisterWait
  3143.  
  3144.  
  3145.  
  3146.                                                                          66
  3147.  
  3148.           ERR_NO_MEMORY       -- This error will occur when there is not
  3149.                               enough memory to allocate the required data
  3150.                               structures.
  3151.  
  3152.           ERR_INVALID_PORT    -- This error can occur when the
  3153.                               communication port specified in the 'com'
  3154.                               parameter was not a valid opened port.
  3155.  
  3156.           Additional Information Return Codes
  3157.  
  3158.           ERR_OK              -- No error occurred.
  3159.  
  3160.           Description
  3161.  
  3162.           This routine is used to register a string for AvidSendSearch to
  3163.           scan for.  This routine puts the wait string in a linked list. 
  3164.           This routine can be called as many times as required.  Each time
  3165.           it is called another wait string gets added to the linked list. 
  3166.           The value that is registered with AvidRegisterWait is the same
  3167.           value that AvidSendSearch will return if the wait string is
  3168.           found.  Wait strings can also be specified as a switch to
  3169.           AvidSendSearch.  This way calling AvidRegisterWait directly is
  3170.           not required.
  3171.  
  3172.           Examples
  3173.  
  3174.           The following example registers the specified string for
  3175.           AvidSendSearch to wait for.  If the string is found,
  3176.           AvidSendSearch will return 100.
  3177.  
  3178.           err = AvidRegisterWait(AVID, com, 100,
  3179.                                       "This is a string", &add_info, "");
  3180.  
  3181.           See Also
  3182.  
  3183.           AvidRegisterSend, AvidSendSearch (Especially the 1w switch)
  3184.  
  3185.  
  3186.  
  3187.  
  3188.  
  3189.  
  3190.  
  3191.  
  3192.  
  3193.  
  3194.  
  3195.  
  3196.  
  3197.                                                            AvidRegisterWait
  3198.  
  3199.  
  3200.  
  3201.                                                                          67
  3202.  
  3203.  
  3204.           AvidSend - Send a String
  3205.  
  3206.           err = AvidSend(AVID, com, s, (int *)&add_info, opts)
  3207.  
  3208.           Parameter Description
  3209.  
  3210.           int err;       -- Return code.
  3211.  
  3212.           AVID           -- System parameter that must always be specified.
  3213.  
  3214.           int com;       -- The AutoLibrary port number.
  3215.  
  3216.           char *s;       -- This is the string to send.
  3217.  
  3218.           int *add_info; -- Additional return information.
  3219.  
  3220.           char *opts;    -- This is the input parameter for options.
  3221.  
  3222.           Options
  3223.  
  3224.           _b'num'   -- This changes the number of milliseconds to delay
  3225.                     before sending the first character of the string.  The
  3226.                     specified value will replace the default only for this
  3227.                     invocation.  Use AvidInitAutoLibrary or AvidOpenPort to
  3228.                     change the defaults permanently. (Default is 0).
  3229.  
  3230.           _B'num'   -- This changes the number of milliseconds to delay
  3231.                     between each character sent.  The specified value will
  3232.                     replace the default only for this invocation.  Use
  3233.                     AvidInitAutoLibrary or AvidOpenPort to change the
  3234.                     defaults permanently. (Default is 0).
  3235.  
  3236.           .N'num'   -- This is the number of null characters in the string. 
  3237.                     For example, .N'3' would be specified for the string
  3238.                     "\n\r\0\0abc\0".
  3239.  
  3240.           Return Codes
  3241.  
  3242.           ERR_OK              -- No error occurred.
  3243.  
  3244.           ERR_NOT_INITIALIZED -- This error is returned when
  3245.                               AvidInitAutoLibrary is not called before this
  3246.                               routine is called.
  3247.  
  3248.           ERR_COMM_PACKAGE    -- This error can occur when the
  3249.                               communication package cannot send through the
  3250.  
  3251.  
  3252.                                                                    AvidSend
  3253.  
  3254.  
  3255.  
  3256.                                                                          68
  3257.  
  3258.                               communication port correctly.  When this
  3259.                               error occurs, the parameter 'add_info' will
  3260.                               contain the actual error returned by the
  3261.                               communication package.
  3262.  
  3263.           ERR_NO_STRING_SPECIFIED  -- This error occurs when there was no
  3264.                                    string specified.
  3265.  
  3266.           ERR_INVALID_PORT    -- This error can occur when the
  3267.                               communication port specified in the 'com'
  3268.                               parameter was not a valid opened port.
  3269.  
  3270.           Additional Information Return Codes
  3271.  
  3272.           ERR_OK         -- No error occurred.
  3273.  
  3274.           <system err>   -- When ERR_COMM_PACKAGE is returned, 'add_info'
  3275.                          contains the actual error returned by the
  3276.                          communication package.
  3277.  
  3278.           Description
  3279.  
  3280.           This routine sends the specified string.
  3281.  
  3282.           Examples
  3283.  
  3284.           The following example sends the specified string.
  3285.  
  3286.           err = AvidSend(AVID, com, "Hello\r", &add_info, "");
  3287.  
  3288.           See Also
  3289.  
  3290.           AvidRegisterSend, CommInterfaceSend, AvidSendSearch
  3291.  
  3292.  
  3293.  
  3294.  
  3295.  
  3296.  
  3297.  
  3298.  
  3299.  
  3300.  
  3301.  
  3302.  
  3303.  
  3304.  
  3305.  
  3306.  
  3307.                                                                    AvidSend
  3308.  
  3309.  
  3310.  
  3311.                                                                          69
  3312.  
  3313.  
  3314.           AvidSendSearch - Send Strings then Search
  3315.  
  3316.           s_found = AvidSendSearch(AVID, com,
  3317.                    (long)r_timeout, (long)e_timeout, (int *)&add_info,
  3318.                                            opts, (long *)&actual, cap)
  3319.  
  3320.           Parameter Description
  3321.  
  3322.           int s_found;        -- The registered value of the string that
  3323.                               was found.  ERR_SNF, which is equal to zero,
  3324.                               is returned if none of the registered strings
  3325.                               were found.
  3326.  
  3327.           AVID                -- System parameter that must always be
  3328.                               specified.
  3329.  
  3330.           int com;            -- The opened communication port.
  3331.  
  3332.           long r_timeout;     -- The number of seconds to scan for the
  3333.                               strings in the wait-list.  The timeout value
  3334.                               starts over after each character received. 
  3335.                               (A repeating timeout)
  3336.  
  3337.                               The parameter constant AVID_NO_TIMEOUT will
  3338.                               cause AvidSendSearch to never timeout due to
  3339.                               a repeating timeout.
  3340.  
  3341.           long e_timeout;     -- The number of seconds to scan for the
  3342.                               strings in the wait-list.  The timeout value
  3343.                               does NOT start over after each character
  3344.                               received.  (An ending timeout)
  3345.  
  3346.                               The parameter constant AVID_NO_TIMEOUT will
  3347.                               cause AvidSendSearch to never timeout due to
  3348.                               an ending timeout.
  3349.  
  3350.           int *add_info;      -- Additional return information.
  3351.  
  3352.           char *opts;         -- This is the input parameter for options.
  3353.  
  3354.           <long *actual;>     -- This is the actual number of characters
  3355.                               captured.  May not equal strlen(cap) if cap
  3356.                               received null characters as part of the data.
  3357.                               (This parameter is optional see the +c and
  3358.                               -c options below.)
  3359.  
  3360.  
  3361.  
  3362.                                                              AvidSendSearch
  3363.  
  3364.  
  3365.  
  3366.                                                                          70
  3367.  
  3368.           <char *cap;>        -- This is the capture string. (This
  3369.                               parameter is optional, see the +c and -c
  3370.                               options below.)
  3371.  
  3372.           Options
  3373.  
  3374.           +c'size'       -- This will cause AvidSendSearch to capture each
  3375.                          received character until 'size' number of
  3376.                          characters have been received.  The captured
  3377.                          string will be smaller that 'size' if a timeout
  3378.                          occurs or one of the strings in the wait-list was
  3379.                          found.
  3380.  
  3381.           -c'size'       -- This will cause AvidSendSearch to capture
  3382.                          received characters until one of the strings in
  3383.                          the wait-list was found or a timeout occurred. 
  3384.                          Truncation will occur if more than 'size' number
  3385.                          of characters are received before AvidSendSearch
  3386.                          is finished.
  3387.  
  3388.           .d'drain_time' -- This is the drain time in seconds.  The drain
  3389.                          time will start over with each new received
  3390.                          character. (Repeating drain)
  3391.  
  3392.           .D'drain_time' -- This is the drain time in seconds.  The drain
  3393.                          time will NOT start over with each new received
  3394.                          character. (Ending drain)
  3395.  
  3396.           1w'string'     -- This is a wait string.  AvidSendSearch will
  3397.                          return 1 if the string is found.  Numbers 1
  3398.                          through 9 are valid for this option.  For example,
  3399.                          2w'string' will register 'string' with 2 and
  3400.                          9w'string' will register it with 9.
  3401.  
  3402.           .s'string'     -- This is a send string.
  3403.  
  3404.           Return Codes
  3405.  
  3406.           <registered value>  -- When one of the wait strings is found, the
  3407.                               registered value is returned.
  3408.  
  3409.           ERR_SNF             -- SNF (String Not Found).  This is returned
  3410.                               when none of the wait strings were found. 
  3411.                               The variable 'add_info' can be tested to find
  3412.                               out additional information about why ERR_SNF
  3413.                               was returned.  The possible values for
  3414.  
  3415.  
  3416.  
  3417.                                                              AvidSendSearch
  3418.  
  3419.  
  3420.  
  3421.                                                                          71
  3422.  
  3423.                               'add_info' are ERR_ENDING_TIMEOUT,
  3424.                               ERR_REPEAT_TIMEOUT, and ERR_CAPTURE_FULL.
  3425.  
  3426.           ERR_NOT_INITIALIZED -- This error is returned when
  3427.                               AvidInitAutoLibrary is not called before this
  3428.                               routine is called.
  3429.  
  3430.           ERR_NO_MEMORY       -- This error can be returned if the .s or 1w
  3431.                               switch is used.  It is possible for
  3432.                               AvidRegisterSend and AvidRegisterWait to not
  3433.                               have the required memory to allocate data
  3434.                               structures.
  3435.  
  3436.           ERR_COMM_PACKAGE    -- This error can occur when the strings in
  3437.                               the send-list are being sent or when
  3438.                               characters are being read looking for the
  3439.                               strings in the wait-list.  When this error
  3440.                               occurs, the parameter 'add_info' will contain
  3441.                               the actual error returned by the
  3442.                               communication package.
  3443.  
  3444.           ERR_INVALID_PORT    -- This error can occur when the
  3445.                               communication port specified in the 'com'
  3446.                               parameter was not a valid opened port.
  3447.  
  3448.           Additional Information Return Codes
  3449.  
  3450.           ERR_OK              -- No error occurred.
  3451.  
  3452.           <system err>        -- When ERR_COMM_PACKAGE is returned,
  3453.                               'add_info' contains the actual error returned
  3454.                               by the communication package.
  3455.  
  3456.           ERR_REPEAT_TIMEOUT  -- When ERR_SNF is returned and the cause for
  3457.                               the timeout is a Repeating Timeout, this is
  3458.                               the value returned.
  3459.  
  3460.           ERR_ENDING_TIMEOUT  -- When ERR_SNF is returned and the cause is
  3461.                               an Ending Timeout, this is the value
  3462.                               returned.
  3463.  
  3464.           ERR_CAPTURE_FULL    -- When ERR_SNF is returned and the cause is
  3465.                               due to a full capture string, this is the
  3466.                               value returned.
  3467.  
  3468.           Description
  3469.  
  3470.  
  3471.  
  3472.                                                              AvidSendSearch
  3473.  
  3474.  
  3475.  
  3476.                                                                          72
  3477.  
  3478.           This routine is the main routine used for automation. 
  3479.           AvidSendSearch sends all of the strings in the send-list, then
  3480.           scans for the strings in the wait-list.  If one of the strings in
  3481.           the wait-list is found, AvidSendSearch returns with that wait
  3482.           string's registered value.  If none of the wait strings are found
  3483.           within the specified timeout period, AvidSendSearch returns with
  3484.           ERR_SNF.  (SNF is String Not Found).
  3485.  
  3486.           It is possible to capture characters while AvidSendSearch is
  3487.           scanning for the strings in the wait-list using the switches +c
  3488.           or -c.  It is also possible to specify drain times with switches. 
  3489.           If specified, draining will occur after one of the strings in the
  3490.           wait-list is found.
  3491.  
  3492.           The send-list and wait-list can be built by calling
  3493.           AvidRegisterSend and AvidRegisterWait, respectively.  The send-
  3494.           list and wait-list can also be built in AvidSendSearch by using
  3495.           switches.  Using switches eliminates the need to call
  3496.           AvidRegisterSend and AvidRegisterWait.
  3497.  
  3498.           Examples
  3499.  
  3500.           The following example sends the string "exit\r" then waits for
  3501.           the string "login:".  Calls to AvidRegisterSend and
  3502.           AvidRegisterWait are used to add the strings to the linked list
  3503.           for AvidSendSearch.
  3504.  
  3505.           /* Register the send string. */
  3506.           AvidRegisterSend(AVID, com, "exit\r", &add_info, "");
  3507.  
  3508.           /* Register the wait string. */
  3509.           AvidRegisterWait(AVID, com, 1, "login:", &add_info, "");
  3510.  
  3511.           /* Send the exit command, then wait for the login: prompt. */
  3512.           if (AvidSendSearch(AVID, com, (long)5, (long)45,
  3513.                                               &add_info, "") <= ERR_SNF)
  3514.                   printf("Exit failed\n");
  3515.  
  3516.           The following example is the same as the one above, except the
  3517.           send string and wait string are registered by using
  3518.           AvidSendSearch switches.
  3519.  
  3520.           /* Send the exit command, then wait for the login: prompt. */
  3521.           if (AvidSendSearch(AVID, com, (long)5, (long)45,
  3522.                          &add_info, ".s'exit\r' 1w'login:'") <= ERR_SNF)
  3523.               printf("Exit failed\n");
  3524.  
  3525.  
  3526.  
  3527.                                                              AvidSendSearch
  3528.  
  3529.  
  3530.  
  3531.                                                                          73
  3532.  
  3533.           Notice in the following example that it is possible to add more
  3534.           than one wait string using AvidRegisterWait.  AvidSendSearch will
  3535.           return the registered string value of the string it finds.  In
  3536.           this example, either 1 or 2.
  3537.  
  3538.           /* Register the send string. */
  3539.           AvidRegisterSend(AVID, com, "exit\r", &add_info, "");
  3540.  
  3541.           /* Register the wait string. */
  3542.           AvidRegisterWait(AVID, com, 1, "login:", &add_info, "");
  3543.  
  3544.           /* Register the wait string. */
  3545.           AvidRegisterWait(AVID, com, 2, "Enter Data Switch Number:",      
  3546.                                                     &add_info, "");
  3547.  
  3548.           /* Send the exit command, then wait for the login: prompt. */
  3549.           if (AvidSendSearch(AVID, com, (long)5, (long)45,
  3550.                                                &add_info, "") <= ERR_SNF)
  3551.               printf("Exit failed\n");
  3552.  
  3553.           The following is the same as the example above except
  3554.           AvidSendSearch is used to register the wait strings.
  3555.  
  3556.           /* Register the send string. */
  3557.           AvidRegisterSend(AVID, com, "exit\r", &add_info, "");
  3558.  
  3559.           /* Send the exit command, then wait for the login: prompt. */
  3560.           if (AvidSendSearch(AVID, com, (long)5, (long)45, &add_info,
  3561.                     "1w'login:' 2w'Enter Data Switch Number:'") <= ERR_SNF)
  3562.               printf("Exit failed\n");
  3563.  
  3564.           The following example shows how to capture information using the
  3565.           negative capture switch.  The negative capture is used when the
  3566.           wait string follows the information that needs to be captured. 
  3567.           Suppose, for example, sending the command 'weather\r' is a host
  3568.           command that displays todays weather forecast.  A segment of what
  3569.           this command returns might be...
  3570.  
  3571.                November 17, 1990
  3572.                Sunny
  3573.                Wind gusts to 30 mph
  3574.                Temperature 43 F
  3575.                No Rain
  3576.  
  3577.           or the following segment is also possible...
  3578.  
  3579.                November 18, 1990
  3580.  
  3581.  
  3582.                                                              AvidSendSearch
  3583.  
  3584.  
  3585.  
  3586.                                                                          74
  3587.  
  3588.                Partly cloudy
  3589.                Mild wind of 2 mph
  3590.                Temperature 35 F
  3591.                No Rain
  3592.  
  3593.           The wind speed needs to be captured.  However, the text before
  3594.           the wind speed is never consistent.  Therefore, it is impossible
  3595.           to key off of a string before the value to be captured.  The
  3596.           string "mph", however, is always displayed after the wind speed. 
  3597.           With this consistency, it is possible to capture the wind speed
  3598.           with a negative capture string.  The following example will do
  3599.           it.
  3600.  
  3601.           if (AvidSendSearch(AVID, com, (long)5, (long)45, &add_info,
  3602.                                     ".s'weather\r' 1w'mph' -c'3'",
  3603.                                     (long *)&actual, captured) <= ERR_SNF)
  3604.               printf("Failed\n");
  3605.  
  3606.           The capture string for the first sample segment would have the
  3607.           string "30 " and for the second sample segment would have the
  3608.           string " 2 ".  In each case, the capture string is the last 3
  3609.           characters before the string 'mph'.
  3610.  
  3611.           A positive capture is used when the string to key off of is
  3612.           before the information to be captured.  Using the sample segments
  3613.           from the weather example, notice that the string "Temperature" is
  3614.           always displayed before the temperature.  Therefore, a positive
  3615.           capture can be done.  The following code segment will do it.
  3616.  
  3617.           if (AvidSendSearch(AVID, com, (long)5, (long)45, &add_info,
  3618.                                             "1w'Temperature'") <= ERR_SNF)
  3619.               printf("Failed\n");
  3620.  
  3621.           if (AvidSendSearch(AVID, com, (long)5, (long)45, &add_info,
  3622.                                       "+c'4' 1w'F' .d'1' .D'10'",
  3623.                                      (long *)&actual, captured) < ERR_SNF)
  3624.               printf("Failed\n");
  3625.  
  3626.           The first call to AvidSendSearch continues from where the wind
  3627.           speed was captured to the string "Temperature".  The second call
  3628.           to AvidSendSearch captures the next 4 characters.  In case the
  3629.           temperature is in the 100's, 4 characters are captured.  The C
  3630.           function sscanf can be used to filter out the trailing character
  3631.           if it is not valid.
  3632.  
  3633.           Notice that the wait switch 1w'F' was also specified.  This will
  3634.           cause AvidSendSearch to return if the string "F" is found.  Also,
  3635.  
  3636.  
  3637.                                                              AvidSendSearch
  3638.  
  3639.  
  3640.  
  3641.                                                                          75
  3642.  
  3643.           notice that the drain switches .d'1' and .D'10' were specified. 
  3644.           These switches will cause the rest of the 'weather' command to be
  3645.           read in and ignored.  In this example, the drain switches would
  3646.           cause 'No Rain' to be ignored.
  3647.  
  3648.           See Also
  3649.  
  3650.           AvidRegisterSend, AvidRegisterWait, AvidDrainPort
  3651.  
  3652.  
  3653.  
  3654.  
  3655.  
  3656.  
  3657.  
  3658.  
  3659.  
  3660.  
  3661.  
  3662.  
  3663.  
  3664.  
  3665.  
  3666.  
  3667.  
  3668.  
  3669.  
  3670.  
  3671.  
  3672.  
  3673.  
  3674.  
  3675.  
  3676.  
  3677.  
  3678.  
  3679.  
  3680.  
  3681.  
  3682.  
  3683.  
  3684.  
  3685.  
  3686.  
  3687.  
  3688.  
  3689.  
  3690.  
  3691.  
  3692.                                                              AvidSendSearch
  3693.  
  3694.  
  3695.  
  3696.                                                                          76
  3697.  
  3698.  
  3699.           AvidVersion - Print Version and Copyright Information
  3700.  
  3701.           err = AvidVersion(AVID, (int *)&add_info, opts)
  3702.  
  3703.           Parameter Description
  3704.  
  3705.           int err;       -- Return code.
  3706.  
  3707.           AVID           -- System parameter that must always be specified.
  3708.  
  3709.           int *add_info; -- Additional return information.
  3710.  
  3711.           char *opts;    -- This is the input parameter for options.
  3712.  
  3713.           Options
  3714.  
  3715.           NONE
  3716.  
  3717.           Return Codes
  3718.  
  3719.           ERR_OK    -- No error occurred.
  3720.  
  3721.           Additional Information Return Codes
  3722.  
  3723.           ERR_OK    -- No error occurred.
  3724.  
  3725.           Description
  3726.  
  3727.           This routine prints the version and copyright information.
  3728.  
  3729.           Examples
  3730.  
  3731.           The following example will display the version and copyright
  3732.           information.
  3733.  
  3734.           err = AvidVersion(AVID, &add_info, "");
  3735.  
  3736.  
  3737.  
  3738.  
  3739.  
  3740.  
  3741.  
  3742.  
  3743.  
  3744.  
  3745.  
  3746.  
  3747.                                                                 AvidVersion
  3748.  
  3749.  
  3750.  
  3751.                                                                          77
  3752.  
  3753.  
  3754.           EveryChar - Called with Every Character Received
  3755.  
  3756.           (void) EveryChar(c)
  3757.  
  3758.           Parameter Description
  3759.  
  3760.           int c;    -- The character that was received.
  3761.  
  3762.           Options
  3763.  
  3764.           Not Applicable
  3765.  
  3766.           Return Codes
  3767.  
  3768.           Not Applicable
  3769.  
  3770.           Description
  3771.  
  3772.           This routine is different from the other routines: the
  3773.           AutoLibrary(tm) Program-Playback tool calls this routine with
  3774.           each received character.  You must supply this routine in your
  3775.           code.  This will give your applications the opportunity to print
  3776.           each received character.  If your application does not need this
  3777.           feature and you do not want the overhead of this routine, simply
  3778.           remove the call from CommInterfaceRead.
  3779.  
  3780.           Examples
  3781.  
  3782.           This example prints each received character to the screen.  By
  3783.           putting this implementation of EveryChar in your application,
  3784.           each received character will be printed to the screen.  EveryChar
  3785.           could also be used to log every character to a file.  Also, see
  3786.           the example in AvidConvert.
  3787.  
  3788.           /*****/
  3789.           void EveryChar(c)
  3790.           int c;
  3791.           /*****/
  3792.           {
  3793.               printf("%c", c);
  3794.           }
  3795.  
  3796.           This example does nothing with each received character, which is
  3797.           completely valid.  Also, it is possible to remove the call to
  3798.           EveryChar in CommInterfaceRead, which is only important if you do
  3799.           not want to overhead of calling EveryChar.
  3800.  
  3801.  
  3802.                                                                   EveryChar
  3803.  
  3804.  
  3805.  
  3806.                                                                          78
  3807.  
  3808.  
  3809.           /*****/
  3810.           void EveryChar(c)
  3811.           int c;
  3812.           /*****/
  3813.           {
  3814.               c = c; /* for compiler. */
  3815.           }
  3816.  
  3817.           See Also
  3818.  
  3819.           AvidConvert, CommInterfaceRead
  3820.  
  3821.  
  3822.  
  3823.  
  3824.  
  3825.  
  3826.  
  3827.  
  3828.  
  3829.  
  3830.  
  3831.  
  3832.  
  3833.  
  3834.  
  3835.  
  3836.  
  3837.  
  3838.  
  3839.  
  3840.  
  3841.  
  3842.  
  3843.  
  3844.  
  3845.  
  3846.  
  3847.  
  3848.  
  3849.  
  3850.  
  3851.  
  3852.  
  3853.  
  3854.  
  3855.  
  3856.  
  3857.                                                                   EveryChar
  3858.  
  3859.  
  3860.  
  3861.                                                                          79
  3862.  
  3863.  
  3864.           Reference Guide for Interface Routines
  3865.  
  3866.           This section describes the routines that interface to your
  3867.           communication package and describes how to create interface
  3868.           routines for other communication packages.
  3869.  
  3870.           Note:  The source code discussed in this section can be found in
  3871.           intface.c.
  3872.  
  3873.  
  3874.  
  3875.                                                                          80
  3876.  
  3877.  
  3878.           CommInterfaceClose - Close port
  3879.  
  3880.           err = CommInterfaceClose(com, (int *)&add_info, opts)
  3881.  
  3882.           Parameter Description
  3883.  
  3884.           int err;       -- The returned status.
  3885.  
  3886.           int com;       -- The AutoLibrary communication port.
  3887.  
  3888.           int *add_info; -- Additional return information.
  3889.  
  3890.           char *opts;    -- Options.
  3891.  
  3892.           Options
  3893.  
  3894.           See AvidClose
  3895.  
  3896.           Return Codes
  3897.  
  3898.           ERR_OK              -- No error occurred.
  3899.  
  3900.           ERR_COMM_PACKAGE    -- This error can occur when the
  3901.                               communication package cannot correctly close
  3902.                               the communication port.  The parameter
  3903.                               'add_info' will contain the actual
  3904.                               communication packages error code.
  3905.  
  3906.           Additional Information Return Codes
  3907.  
  3908.           ERR_OK         -- No error occurred.
  3909.  
  3910.           <system err>   -- When ERR_COMM_PACKAGE is returned, this
  3911.                          variable contains the actual error returned by the
  3912.                          communication package.
  3913.  
  3914.           Description
  3915.  
  3916.           This routine is used to close the communication port.  Your code
  3917.           must not call this routine directly.  This routine will need to
  3918.           be modified to support your communication package.  See the
  3919.           System Requirements section for a list of supported communication
  3920.           packages.
  3921.  
  3922.           Porting to other communication packages
  3923.  
  3924.  
  3925.  
  3926.                                                          CommInterfaceClose
  3927.  
  3928.  
  3929.  
  3930.                                                                          81
  3931.  
  3932.           The following sample source code is written to interface with the
  3933.           Greenleaf CommLib.  To support a different communication package,
  3934.           use this code as a template, then code according to the
  3935.           specifications of the communication package.
  3936.  
  3937.           The call to 'asiquit' and the literal ASSUCCESS are unique to the
  3938.           Greenleaf CommLib and would need to change to support a different
  3939.           communication package.
  3940.  
  3941.           When this routine works correctly, ERR_OK must be returned in
  3942.           'add_info' and as the return status.  When this routine fails for
  3943.           any reason, the return status must be ERR_COMM_PACKAGE.  When
  3944.           ERR_COMM_PACKAGE is returned, 'add_info' should be set to the
  3945.           actual error from the communication package.
  3946.  
  3947.           /********************************************************/
  3948.               int         /* The return status. */
  3949.           CommInterfaceClose (com, info, opts)
  3950.               int com;    /* The AutoLibrary communication port. */
  3951.               int *info;
  3952.               char *opts; /* Options. */
  3953.           /********************************************************/
  3954.           {
  3955.           int err;
  3956.  
  3957.               opts = opts; /* for compiler */
  3958.  
  3959.               /* Start out with no errors. */
  3960.               *info = ERR_OK;
  3961.  
  3962.               err = asiquit (comlist[com]->hw_port);
  3963.               if (err != ASSUCCESS) {
  3964.                *info = err;
  3965.                return(ERR_COMM_PACKAGE);
  3966.               }
  3967.  
  3968.               return(ERR_OK);
  3969.           }
  3970.  
  3971.           See Also
  3972.  
  3973.           AvidClosePort, Actual source code.
  3974.  
  3975.  
  3976.  
  3977.  
  3978.  
  3979.  
  3980.  
  3981.                                                          CommInterfaceClose
  3982.  
  3983.  
  3984.  
  3985.                                                                          82
  3986.  
  3987.  
  3988.           CommInterfaceOpen - Open Port
  3989.  
  3990.           err = CommInterfaceOpen(com, device, (int *)&add_info, opts)
  3991.  
  3992.           Parameter Description
  3993.  
  3994.           int err;       -- The return status.
  3995.  
  3996.           int com;       -- The AutoLibrary port number.
  3997.  
  3998.           char *device;  -- The device name.  (For example, "com1" or
  3999.                          "com2".)
  4000.  
  4001.           int *add_info; -- Additional return information.
  4002.  
  4003.           char *opts;    -- Options.
  4004.  
  4005.           Options
  4006.  
  4007.           See AvidOpenPort
  4008.  
  4009.           Return Codes
  4010.  
  4011.           ERR_OK              -- No error occurred.
  4012.  
  4013.           ERR_COMM_PACKAGE    -- This error occurs when the communication
  4014.                               package cannot open the communication port
  4015.                               correctly.  When this error occurs, the
  4016.                               parameter 'add_info' will contain the actual
  4017.                               error returned by the communication package.
  4018.  
  4019.           Additional Information Return Codes
  4020.  
  4021.           ERR_OK         -- No error occurred.
  4022.  
  4023.           <system err>   -- When ERR_COMM_PACKAGE is returned, 'add_info'
  4024.                          contains the actual error returned by the
  4025.                          communication package.
  4026.  
  4027.           Description
  4028.  
  4029.           This routine is used to open the communication port.  Your code
  4030.           must not call this routine directly.  This routine will need to
  4031.           be modified to support your communication package.  See the
  4032.           System Requirements section for a list of supported communication
  4033.           packages.
  4034.  
  4035.  
  4036.                                                           CommInterfaceOpen
  4037.  
  4038.  
  4039.  
  4040.                                                                          83
  4041.  
  4042.  
  4043.           Porting to other communication packages
  4044.  
  4045.           The best way to describe how to port CommInterfaceOpen is a piece
  4046.           at a time.  You will want to refer to the final version of
  4047.           CommInterfaceOpen at the end of this section as you read about
  4048.           this routine.  By referring to the final version you will be able
  4049.           to see where the many code fragments fit in.  The following line
  4050.           of code saves the information required to interface with the
  4051.           Greenleaf CommLib.
  4052.  
  4053.           /* Save the Greenleaf port number. */
  4054.           comlist[com]->hw_port = port_num;
  4055.  
  4056.           The Greenleaf port number 'port_num' must be saved for later use
  4057.           in the routines CommInterfaceClose, CommInterfaceRead, and
  4058.           CommInterfaceSend, since each of these routines make calls to
  4059.           Greenleaf routines.  Note that the Greenleaf port number
  4060.           'port_num' will not always be equal to the AutoLibrary port
  4061.           number 'com', i.e., com != comlist[com]->hw_port.  The
  4062.           AutoLibrary port number is used by AutoLibrary routines to get
  4063.           information from the 'comlist' data structure.  Where as, the
  4064.           Greenleaf port number is used to identify a port number to
  4065.           communicate with.
  4066.  
  4067.           The following code segment shows a call that opens a Greenleaf
  4068.           communication port.
  4069.  
  4070.           err=asiopen(comlist[com]->hw_port, mode, 8192,
  4071.                                            512, 9600, P_ODD, 1, 8, 0, 0);
  4072.           if (err != ASSUCCESS) {
  4073.               *info = err;
  4074.               return(ERR_COMM_PACKAGE);
  4075.           }
  4076.  
  4077.           This call opens a communication port with a receive buffer of
  4078.           8192 bytes, transmit buffer of 512 bytes, baud rate of 9600, odd
  4079.           parity, one stop bit, and 8 bits per word.  This hard coded call
  4080.           to 'asiopen' is valid, since the AutoLibrary(tm) Program-Playback
  4081.           tool will work as long as a port gets opened.  However, since
  4082.           hard coded opens are restrictive, switches have been defined to
  4083.           support opening a communication port in different ways.  For
  4084.           example, the switch -b'4800' requests that the port be opened at
  4085.           4800 baud.  The switch .2 specifies 2 stop bits and rx'1024'
  4086.           requests a receive buffer of 1K.
  4087.  
  4088.  
  4089.  
  4090.  
  4091.                                                           CommInterfaceOpen
  4092.  
  4093.  
  4094.  
  4095.                                                                          84
  4096.  
  4097.           It is the responsibility of CommInterfaceOpen to support these
  4098.           switches.  (It is ok to add switches that are unique to your
  4099.           communication package.)
  4100.  
  4101.           Before describing switches, I would like to show the following
  4102.           implementation of CommInterfaceOpen, which is instructive because
  4103.           it only shows the required code.  Additional code is recommended,
  4104.           which will be shown later.
  4105.  
  4106.  
  4107.  
  4108.  
  4109.  
  4110.  
  4111.  
  4112.  
  4113.  
  4114.  
  4115.  
  4116.  
  4117.  
  4118.  
  4119.  
  4120.  
  4121.  
  4122.  
  4123.  
  4124.  
  4125.  
  4126.  
  4127.  
  4128.  
  4129.  
  4130.  
  4131.  
  4132.  
  4133.  
  4134.  
  4135.  
  4136.  
  4137.  
  4138.  
  4139.  
  4140.  
  4141.  
  4142.  
  4143.  
  4144.  
  4145.  
  4146.                                                           CommInterfaceOpen
  4147.  
  4148.  
  4149.  
  4150.                                                                          85
  4151.  
  4152.  
  4153.           /********************************************************/
  4154.               int
  4155.           CommInterfaceOpen (com, device, info, opts)
  4156.               int com;      /* The AutoLibrary communication port. */
  4157.               char *device; /* The device name. */
  4158.               int *info;
  4159.               char *opts;   /* Options. */
  4160.           /********************************************************/
  4161.           {
  4162.           int mode, err;
  4163.  
  4164.               /* Start out with no errors. */
  4165.               *info = ERR_OK;
  4166.  
  4167.               /* For Greenleaf COM1 is defined as 0. */
  4168.               port_num--;
  4169.  
  4170.               /* Save the port number for closing. */
  4171.               comlist[com]->hw_port = port_num;
  4172.  
  4173.               /* No ASCII device names in this comm package. */
  4174.               comlist[com]->hw_port_name = (char *)NULL;
  4175.  
  4176.               mode = ASCII | ASINOUT | NORMALRX;
  4177.  
  4178.               err = asiopen (comlist[com]->hw_port, mode, 8192,
  4179.                                         512, 9600, P_ODD, 1, 8, 0, 0);
  4180.               if (err != ASSUCCESS) {
  4181.                   *info = err;
  4182.                   return(ERR_COMM_PACKAGE);
  4183.               }
  4184.  
  4185.               err = asixon(comlist[com]->hw_port, 30, 70, XON, XOFF);
  4186.               if (err != ASSUCCESS) {
  4187.                   *info = err;
  4188.                   return(ERR_COMM_PACKAGE);
  4189.               }
  4190.  
  4191.               return(ERR_OK);
  4192.           }
  4193.  
  4194.           The second line of code decrements 'port_num'.  This is required
  4195.           because the Greenleaf CommLib defines 0 for com1, 1 for com2, and
  4196.           so on.  Your communication package may or may not have to
  4197.           decrement 'port_num'.
  4198.  
  4199.  
  4200.  
  4201.                                                           CommInterfaceOpen
  4202.  
  4203.  
  4204.  
  4205.                                                                          86
  4206.  
  4207.           We have already looked at the third line of code.  The Greenleaf
  4208.           port number ('port_num') is saved in the 'comlist' data structure
  4209.           for later use by the other interface routines.
  4210.  
  4211.           The forth line of code saves a pointer to the device name in the
  4212.           'comlist' data structure for later use for the same reasons the
  4213.           port number is saved.  This example sets this value to NULL
  4214.           because the Greenleaf CommLib does not use device names.  If your
  4215.           communication package uses device names, this field would be used
  4216.           to save a pointer to the name for the interface routines
  4217.           CommInterfaceClose, CommInterfaceRead, and CommInterfaceSend. 
  4218.           The device name field 'hw_port_name' is important only if your
  4219.           communication package refers to ports with text strings instead
  4220.           of numbers.  Just remember that 'comlist[com]->hw_port_name' is a
  4221.           pointer.  Use 'malloc' to dynamically allocate the memory needed
  4222.           to store the device name, then in CommInterfaceClose free the
  4223.           memory.
  4224.  
  4225.           The remaining code in the above example opens a Greenleaf
  4226.           communication port with hard coded parameters.  This
  4227.           implementation of CommInterfaceOpen contains the bare minimum for
  4228.           the AutoLibrary(tm) Program-Playback tool to work correctly.  If
  4229.           your application is always to be opened with the same parameters,
  4230.           an implementation like this may be enough.  However, more code is
  4231.           required if CommInterfaceOpen is to be flexible.  When opening a
  4232.           communication port there are many options to choose from, like
  4233.           baud rate, number of stop bits, parity, and so on.  To support
  4234.           these different options, we need to add switch processing to
  4235.           CommInterfaceOpen.  For example, the following call to
  4236.           AvidOpenPort opens communication port one (com1) at 4800 baud and
  4237.           even parity.  The defaults are used for the other parameters.
  4238.  
  4239.           AvidOpenPort(AVID, "1", &info, ".b'4800' .e");
  4240.  
  4241.           AvidOpenPort does not process open switches, instead, the
  4242.           switches are passed directly to CommInterfaceOpen.  If we stayed
  4243.           with the previous implementation of CommInterfaceOpen, the open
  4244.           switches ".b'4800' .e" would be ignored.  To support open
  4245.           switches, the option parameter needs to be parsed using
  4246.           AvidProcessOptions.  Here is an example of how CommInterfaceOpen
  4247.           would process the baud rate switch.
  4248.  
  4249.  
  4250.  
  4251.  
  4252.  
  4253.  
  4254.  
  4255.  
  4256.                                                           CommInterfaceOpen
  4257.  
  4258.  
  4259.  
  4260.                                                                          87
  4261.  
  4262.           baud = 9600;  /* default */
  4263.  
  4264.           s_num = 0; /* Required for AvidProcessOptions. */
  4265.           while ((sc = AvidProcessOptions(AVID, opts, "", &control,
  4266.                                              temp_buf, &s_num)) != '\0') {
  4267.               if ((control == '.') && (sc == 'b'))
  4268.                   baud = atoi(temp_buf);
  4269.           }
  4270.  
  4271.           First, the variable 'baud' is set to the default of 9600, which
  4272.           is used if the baud rate switch ( .b'baud' ) is not specified. 
  4273.           The while loop will return each of the switches specified in the
  4274.           'opts' parameter.  The 'if' statement inside the while loop tests
  4275.           for the baud rate switch.  When specified, the new baud rate is
  4276.           set.  The following if statements, when placed inside the while
  4277.           loop, will set the parity to the desired value.
  4278.  
  4279.           if ((o_odd[0] == control) && (o_odd[1] == sc))
  4280.               parity = P_ODD;
  4281.  
  4282.           if ((o_even[0] == control) && (o_even[1] == sc))
  4283.               parity = P_EVEN;
  4284.  
  4285.           The string 'o_odd' is initialized to ".o" and the string 'o_even'
  4286.           is initialized to ".e".  This way the actual switch definition is
  4287.           done in one spot.  The previous example hard coded the baud rate
  4288.           switch, which has the option string 'o_baud'.  The string
  4289.           'o_baud' will be used in the final version of CommInterfaceOpen.
  4290.  
  4291.           The constants P_ODD and P_EVEN are defined in the Greenleaf
  4292.           CommLib.  Since your communication package will be different,
  4293.           these constants will be different.
  4294.  
  4295.           The following while loop shows how the other open options are
  4296.           parsed by AvidProcessOptions.
  4297.  
  4298.           mode = 0;
  4299.           baud = 9600;
  4300.           parity = P_ODD;
  4301.           stop_bits = 1;
  4302.           word_len = 8;
  4303.           dtr = 0;
  4304.           rts = 0;
  4305.           rx_length = 8192;
  4306.           tx_length = 512;
  4307.           strip = ASCII;
  4308.           xon = TRUE;
  4309.  
  4310.  
  4311.                                                           CommInterfaceOpen
  4312.  
  4313.  
  4314.  
  4315.                                                                          88
  4316.  
  4317.  
  4318.           s_num = 0; /* Required for AvidProcessOptions. */
  4319.           while ((sc = AvidProcessOptions (AVID, opts, "", &control,
  4320.                                           temp_buf, &s_num)) != '\0') {
  4321.               if ((o_strip_yes[0] == control) && (o_strip_yes[1] == sc))
  4322.                   strip = ASCII;
  4323.  
  4324.               if ((o_strip_no[0] == control) && (o_strip_no[1] == sc))
  4325.                   strip = BINARY;
  4326.  
  4327.               if ((o_even[0] == control) && (o_even[1] == sc))
  4328.                   parity = P_EVEN;
  4329.  
  4330.               if ((o_odd[0] == control) && (o_odd[1] == sc))
  4331.                   parity = P_ODD;
  4332.  
  4333.               if ((o_none[0] == control) && (o_none[1] == sc))
  4334.                   parity = P_NONE;
  4335.  
  4336.               if ((o_baud[0] == control) && (o_baud[1] == sc))
  4337.                   baud = atoi (temp_buf);
  4338.  
  4339.               if ((o_stop_bits_1[0] == control) &&
  4340.                                               (o_stop_bits_2[1] == sc))
  4341.                   stop_bits = 1;
  4342.  
  4343.               if ((o_stop_bits_2[0] == control) &&
  4344.                                                (o_stop_bits_2[1] == sc))
  4345.                   stop_bits = 2;
  4346.  
  4347.               if ((o_word_len_7[0] == control) && (o_word_len_7[1] == sc))
  4348.                   word_len = 7;
  4349.  
  4350.               if ((o_word_len_8[0] == control) && (o_word_len_8[1] == sc))
  4351.                   word_len = 8;
  4352.  
  4353.               if ((o_dtr[0] == control) && (o_dtr[1] == sc))
  4354.                   dtr = 1;
  4355.  
  4356.               if ((o_xon_yes[0] == control) && (o_xon_yes[1] == sc))
  4357.                   xon = TRUE;
  4358.  
  4359.               if ((o_xon_no[0] == control) && (o_xon_no[1] == sc))
  4360.                   xon = FALSE;
  4361.  
  4362.               if ((o_rx_len[0] == control) && (o_rx_len[1] == sc)) {
  4363.                   temp_long = atol (temp_buf);
  4364.  
  4365.  
  4366.                                                           CommInterfaceOpen
  4367.  
  4368.  
  4369.  
  4370.                                                                          89
  4371.  
  4372.                   rx_length = temp_long;
  4373.               }
  4374.  
  4375.               if ((o_tx_len[0] == control) && (o_tx_len[1] == sc)) {
  4376.                   temp_long = atol (temp_buf);
  4377.                   tx_length = temp_long;
  4378.               }
  4379.           }
  4380.  
  4381.           Your implementation of this while loop may be very different. 
  4382.           Some switches may not apply, like the receive buffer length
  4383.           switch (rx) and the send buffer length switch (tx).  These
  4384.           options were added to CommInterfaceOpen because the Greenleaf
  4385.           CommLib supports changing these buffer sizes at run time.  Your
  4386.           communication package may support other unique features.  If so,
  4387.           make up a switch that can be used to invoke the feature.  Include
  4388.           the new switch in intface.c.  Try to make the new switch unique
  4389.           by checking the other switches in al_sys.h.
  4390.  
  4391.           Once you have chosen a switch, it is possible to reserve it by
  4392.           contacting Avid Software.  Also, I am interested in supporting as
  4393.           many communications packages as possible, so send in your ported
  4394.           code for possible inclusion in the core product.
  4395.  
  4396.           The 3 major pieces of CommInterfaceOpen have been described. 
  4397.           First, the port number or device name is saved for later use. 
  4398.           Next, the switches are parsed, and finally the call is made to
  4399.           the communication package to open the port.  However, before
  4400.           showing a complete listing of CommInterfaceOpen, it is important
  4401.           to understand what the first part of CommInterfaceOpen does.  The
  4402.           following 'if' statements allow communication ports to be
  4403.           specified in 2 different ways.
  4404.  
  4405.           /* Let valid input for device be com1 or 1, for example. */
  4406.           if (sscanf (device, "com%d", &port_num) == 0) {
  4407.  
  4408.               if (sscanf (device, "%d", &port_num) == 0) {
  4409.                   *info = ASINVPORT;
  4410.                   return(ERR_COMM_PACKAGE);
  4411.               }
  4412.           }
  4413.  
  4414.           This makes it possible, for instance, to accept communication
  4415.           port 1 as "com1" or as "1".
  4416.  
  4417.  
  4418.  
  4419.  
  4420.  
  4421.                                                           CommInterfaceOpen
  4422.  
  4423.  
  4424.  
  4425.                                                                          90
  4426.  
  4427.           The following 'if' statement returns an error if the
  4428.           communication port number is outside the range possible for the
  4429.           Greenleaf CommLib.
  4430.  
  4431.           /* Make sure wild number did not make it through. */
  4432.           if ((port_num < 1) || (port_num > 17)) {
  4433.               *info = ASINVPORT;
  4434.               return(ERR_COMM_PACKAGE);
  4435.           }
  4436.  
  4437.           Now that everything in CommInterfaceOpen has been described, the
  4438.           following listing shows a complete version.
  4439.  
  4440.  
  4441.  
  4442.  
  4443.  
  4444.  
  4445.  
  4446.  
  4447.  
  4448.  
  4449.  
  4450.  
  4451.  
  4452.  
  4453.  
  4454.  
  4455.  
  4456.  
  4457.  
  4458.  
  4459.  
  4460.  
  4461.  
  4462.  
  4463.  
  4464.  
  4465.  
  4466.  
  4467.  
  4468.  
  4469.  
  4470.  
  4471.  
  4472.  
  4473.  
  4474.  
  4475.  
  4476.                                                           CommInterfaceOpen
  4477.  
  4478.  
  4479.  
  4480.                                                                          91
  4481.  
  4482.  
  4483.           /********************************************************/
  4484.               int
  4485.           CommInterfaceOpen (com, device, info, opts)
  4486.               int com;      /* The AutoLibrary communication port. */
  4487.               char *device; /* The device name. */
  4488.               int *info;
  4489.               char *opts;   /* Options. */
  4490.           /********************************************************/
  4491.           {
  4492.           int mode, word_len, baud, stop_bits, parity, port_num, strip,
  4493.           dtr, rts;
  4494.           unsigned int rx_length, tx_length;
  4495.           char sc, control;
  4496.           char temp_buf[85];
  4497.           int s_num, err;
  4498.           long temp_long;
  4499.  
  4500.               /* Start out with no errors. */
  4501.               *info = ERR_OK;
  4502.  
  4503.               /* Let valid input for device be com1 or 1 (for example) */
  4504.               if (sscanf (device, "com%d", &port_num) == 0) {
  4505.  
  4506.                   if (sscanf (device, "%d", &port_num) == 0) {
  4507.                       *info = ASINVPORT;
  4508.                       return (ERR_COMM_PACKAGE);
  4509.                   }
  4510.               }
  4511.  
  4512.               /* Make sure wild number did not make it through. */
  4513.               if ((port_num < 1) || (port_num > 17)) {
  4514.                   *info = ASINVPORT;
  4515.                   return (ERR_COMM_PACKAGE);
  4516.               }
  4517.  
  4518.               /* For Greenleaf COM1 is defined as 0. */
  4519.               port_num--;
  4520.  
  4521.               /* Save the port number for closing. */
  4522.               comlist[com]->hw_port = port_num;
  4523.  
  4524.               /* No ASCII device names in this comm package. */
  4525.               comlist[com]->hw_port_name = (char *)NULL;
  4526.  
  4527.               mode = 0;
  4528.               baud = 9600;
  4529.  
  4530.  
  4531.                                                           CommInterfaceOpen
  4532.  
  4533.  
  4534.  
  4535.                                                                          92
  4536.  
  4537.               parity = P_ODD;
  4538.               stop_bits = 1;
  4539.               word_len = 8;
  4540.               dtr = 0;
  4541.               rts = 0;
  4542.               rx_length = 8192;
  4543.               tx_length = 512;
  4544.               strip = ASCII;
  4545.               xon = TRUE;
  4546.  
  4547.               s_num = 0; /* Required for AvidProcessOptions. */
  4548.               while ((sc = AvidProcessOptions (AVID, opts, "", &control,
  4549.                                              temp_buf, &s_num)) != '\0') {
  4550.  
  4551.                   if ((o_strip_yes[0] == control) &&
  4552.                                                    (o_strip_yes[1] == sc))
  4553.                       strip = ASCII;
  4554.  
  4555.                   if ((o_strip_no[0] == control) && (o_strip_no[1] == sc))
  4556.                       strip = BINARY;
  4557.  
  4558.                   if ((o_even[0] == control) && (o_even[1] == sc))
  4559.                       parity = P_EVEN;
  4560.  
  4561.                   if ((o_odd[0] == control) && (o_odd[1] == sc))
  4562.                       parity = P_ODD;
  4563.  
  4564.                   if ((o_none[0] == control) && (o_none[1] == sc))
  4565.                       parity = P_NONE;
  4566.  
  4567.                   if ((o_baud[0] == control) && (o_baud[1] == sc))
  4568.                       baud = atoi (temp_buf);
  4569.  
  4570.                   if ((o_stop_bits_1[0] == control) &&
  4571.                                                  (o_stop_bits_2[1] == sc))
  4572.                       stop_bits = 1;
  4573.  
  4574.                   if ((o_stop_bits_2[0] == control) &&
  4575.                                                  (o_stop_bits_2[1] == sc))
  4576.                       stop_bits = 2;
  4577.  
  4578.                   if ((o_word_len_7[0] == control) &&
  4579.                                                   (o_word_len_7[1] == sc))
  4580.                       word_len = 7;
  4581.  
  4582.                   if ((o_word_len_8[0] == control) &&
  4583.                                                   (o_word_len_8[1] == sc))
  4584.  
  4585.  
  4586.                                                           CommInterfaceOpen
  4587.  
  4588.  
  4589.  
  4590.                                                                          93
  4591.  
  4592.                       word_len = 8;
  4593.  
  4594.                   if ((o_dtr[0] == control) && (o_dtr[1] == sc))
  4595.                       dtr = 1;
  4596.  
  4597.                   if ((o_xon_yes[0] == control) && (o_xon_yes[1] == sc))
  4598.                       xon = TRUE;
  4599.  
  4600.                   if ((o_xon_no[0] == control) && (o_xon_no[1] == sc))
  4601.                       xon = FALSE;
  4602.  
  4603.                   if ((o_rx_len[0] == control) && (o_rx_len[1] == sc)) {
  4604.                       temp_long = atol (temp_buf);
  4605.                       rx_length = temp_long;
  4606.                   }
  4607.  
  4608.                   if ((o_tx_len[0] == control) && (o_tx_len[1] == sc)) {
  4609.                       temp_long = atol (temp_buf);
  4610.                       tx_length = temp_long;
  4611.                   }
  4612.               }
  4613.  
  4614.               mode = strip | ASINOUT | NORMALRX;
  4615.  
  4616.               err = asiopen (comlist[com]->hw_port, mode,
  4617.                           rx_length, tx_length, baud, parity, stop_bits,
  4618.                                                      word_len, dtr, rts);
  4619.               if (err != ASSUCCESS) {
  4620.                   *info = err;
  4621.                   return(ERR_COMM_PACKAGE);
  4622.               }
  4623.  
  4624.               if (xon) {
  4625.                   err = asixon(comlist[com]->hw_port, 30, 70, XON, XOFF);
  4626.                   if (err != ASSUCCESS) {
  4627.                       *info = err;
  4628.                       return(ERR_COMM_PACKAGE);
  4629.                   }
  4630.               }
  4631.  
  4632.               return(ERR_OK);
  4633.           }
  4634.  
  4635.           See Also
  4636.  
  4637.           AvidOpenPort, Actual source code.
  4638.  
  4639.  
  4640.  
  4641.                                                           CommInterfaceOpen
  4642.  
  4643.  
  4644.  
  4645.                                                                          94
  4646.  
  4647.  
  4648.           CommInterfaceRead - Read Character
  4649.  
  4650.           c = CommInterfaceRead(com, (long)r_timeout, (long)e_timeout,
  4651.                                                   (int *)&add_info, opts)
  4652.  
  4653.           Parameter Description
  4654.  
  4655.           int c;              -- The character that was read.
  4656.  
  4657.           int com;            -- The AutoLibrary communication port.
  4658.  
  4659.           long r_timeout;     -- The repeating timeout.
  4660.  
  4661.           long e_timeout;     -- The ending timeout.
  4662.  
  4663.           int *add_info;      -- Additional return information.
  4664.  
  4665.           char *opts;         -- Options.
  4666.  
  4667.           Options
  4668.  
  4669.           See AvidRead
  4670.  
  4671.           Return Codes
  4672.  
  4673.           <Received character>     -- No error occurred.  The character is
  4674.                                    returned.
  4675.  
  4676.           ERR_COMM_PACKAGE         -- This error occurs when the
  4677.                                    communication package cannot read the
  4678.                                    communication port correctly.  When this
  4679.                                    error occurs, the parameter 'add_info'
  4680.                                    will contain the actual error returned
  4681.                                    by the communication package.
  4682.  
  4683.           Additional Information Return Codes
  4684.  
  4685.           ERR_OK         -- No error occurred.
  4686.  
  4687.           <system err>   -- When ERR_COMM_PACKAGE is returned, 'add_info'
  4688.                          contains the actual error returned by the
  4689.                          communication package.
  4690.  
  4691.           Description
  4692.  
  4693.  
  4694.  
  4695.  
  4696.                                                           CommInterfaceRead
  4697.  
  4698.  
  4699.  
  4700.                                                                          95
  4701.  
  4702.           This routine is used to read from the communication port.  Your
  4703.           code must not call this routine directly.  This routine will need
  4704.           to be modified to support your communication package.  See the
  4705.           System Requirements section for a list of supported communication
  4706.           packages.
  4707.  
  4708.           Porting to other communication packages
  4709.  
  4710.           You will want to refer to the final version of CommInterfaceRead
  4711.           at the end of this section as you read about this routine.  By
  4712.           referring to the final version you will be able to see where the
  4713.           many code fragments fit in.
  4714.  
  4715.           If timeouts were not required, CommInterfaceRead would be easy. 
  4716.           This routine would simply return the received character, or
  4717.           ERR_EOF when no character was available.  The following code
  4718.           shows this simple implementation.
  4719.  
  4720.  
  4721.  
  4722.  
  4723.  
  4724.  
  4725.  
  4726.  
  4727.  
  4728.  
  4729.  
  4730.  
  4731.  
  4732.  
  4733.  
  4734.  
  4735.  
  4736.  
  4737.  
  4738.  
  4739.  
  4740.  
  4741.  
  4742.  
  4743.  
  4744.  
  4745.  
  4746.  
  4747.  
  4748.  
  4749.  
  4750.  
  4751.                                                           CommInterfaceRead
  4752.  
  4753.  
  4754.  
  4755.                                                                          96
  4756.  
  4757.           /********************************************************/
  4758.               int
  4759.           CommInterfaceRead (com, r_timeout, e_timeout, info, opts)
  4760.               int com;         /* The AutoLibrary communication port. */
  4761.               long r_timeout;  /* The repeating timeout. */
  4762.               long e_timeout;  /* The ending timeout. */
  4763.               int *info;
  4764.               char *opts;      /* Options. */
  4765.           /********************************************************/
  4766.           {
  4767.           int c;
  4768.  
  4769.               /* Start out with no errors. */
  4770.               *info = ERR_OK;
  4771.  
  4772.               c = asigetc (comlist[com]->hw_port);
  4773.               if ((c >=0) && (c <= 0xFF)) {
  4774.                   EveryChar(c);
  4775.                   return(c);
  4776.               }
  4777.  
  4778.               if (c == ASINVPORT) {
  4779.                   *info = ASINVPORT;
  4780.                   return(ERR_COMM_PACKAGE);
  4781.               }
  4782.  
  4783.               if (c == ASNOTSETUP) {
  4784.                   *info = ASNOTSETUP;
  4785.                   return(ERR_COMM_PACKAGE);
  4786.               }
  4787.  
  4788.               return(ERR_EOF);
  4789.           }
  4790.  
  4791.           The above implementation would work.  However, since timeouts are
  4792.           required to successfully automate communications, the
  4793.           AutoLibrary(tm) Program-Playback tool supports 2 types of
  4794.           timeouts:  Repeating Timeouts and Ending Timeouts.  Let's
  4795.           implement Repeating Timeouts first.  It is possible to implement
  4796.           Repeating Timeouts completely from within CommInterfaceRead.  We
  4797.           will find out later this is not possible with Ending Timeouts.
  4798.  
  4799.           To implement Repeating Timeouts, a while loop needs to be added. 
  4800.           The while loop will make repeated calls to the communication
  4801.           package asking for a character until a character is received or
  4802.           until a timeout occurs.  The following implementation supports
  4803.           Repeating Timeouts.
  4804.  
  4805.  
  4806.                                                           CommInterfaceRead
  4807.  
  4808.  
  4809.  
  4810.                                                                          97
  4811.  
  4812.  
  4813.  
  4814.           /********************************************************/
  4815.               int
  4816.           CommInterfaceRead (com, r_timeout, e_timeout, info, opts)
  4817.               int com;         /* The AutoLibrary communication port. */
  4818.               long r_timeout;  /* The repeating timeout. */
  4819.               long e_timeout;  /* The ending timeout. */
  4820.               int *info;
  4821.               char *opts;      /* Options. */
  4822.           /********************************************************/
  4823.           {
  4824.           int c;
  4825.           long seconds;
  4826.  
  4827.               /* Start out with no errors. */
  4828.               *info = ERR_OK;
  4829.  
  4830.               /* Set up for Repeating Timeout. */
  4831.               time(&seconds);
  4832.               r_timeout = r_timeout + seconds;
  4833.  
  4834.               while (1 > 0) {
  4835.  
  4836.                   c = asigetc (comlist[com]->hw_port);
  4837.                   if ((c >=0) && (c <= 0xFF)) {
  4838.                       EveryChar(c);
  4839.                       return(c);
  4840.                   }
  4841.  
  4842.                   if (c == ASBUFREMPTY) {
  4843.  
  4844.                       /* if still no character, check for timeout. */
  4845.                       time(&seconds);
  4846.                       if (seconds >= r_timeout) {
  4847.                           *info = ERR_REPEAT_TIMEOUT;
  4848.                           return(ERR_EOF);
  4849.                       }
  4850.                   }
  4851.               }
  4852.  
  4853.               return(ERR_EOF);
  4854.           }
  4855.  
  4856.           The call to 'time(&seconds)' gets the total number of seconds
  4857.           since Jan 1, 1970.  This number is added to the desired timeout
  4858.           value.  Say, for instance, a Repeating Timeout of 10 seconds was
  4859.  
  4860.  
  4861.                                                           CommInterfaceRead
  4862.  
  4863.  
  4864.  
  4865.                                                                          98
  4866.  
  4867.           specified and the current date and time is June 30, 1991 at
  4868.           18:37:40.  The variable 'r_timeout' would then contain
  4869.           678,321,470 which is 678,321,460 plus 10, where 678,321,460 is
  4870.           the number of seconds from Jan 1, 1970 to Jun 30, 1991.  Once
  4871.           'r_timeout' is initialized this way, it is possible to determine
  4872.           when a timeout should happen.  Each time 'asigetc' is called,
  4873.           which results in no received character, the current system time
  4874.           is compared with 'r_timeout'.  If the system time is greater than
  4875.           or equal to 'r_timeout', a timeout is returned.
  4876.  
  4877.           The above implementation needs some minor but important changes. 
  4878.           The first change is in setting up for the Repeating Timeout. 
  4879.           Instead of...
  4880.  
  4881.           time(&seconds);
  4882.           r_timeout = r_timeout + seconds;
  4883.  
  4884.           the following code is correct.
  4885.  
  4886.           time(&seconds);
  4887.           if (r_timeout < seconds)
  4888.               r_timeout = r_timeout + seconds;
  4889.  
  4890.           The 'if' test is required to support AVID_NO_TIMEOUT, which
  4891.           indicates that a timeout is to never happen.  AVID_NO_TIMEOUT is
  4892.           defined as 2,147,483,600, which is the system time 68 years from
  4893.           now.  Therefore, when 'r_timeout' has this value, incrementing
  4894.           'r_timeout' by 'seconds' is not needed.
  4895.  
  4896.           The next change the above implementation needs is to return an
  4897.           error if 'asigetc' returns with an error.  Therefore, instead
  4898.           of...
  4899.  
  4900.           if (c == ASBUFREMPTY) {
  4901.  
  4902.               /* if still no character, check for timeout. */
  4903.               time(&seconds);
  4904.               if (seconds >= r_timeout) {
  4905.                   *info = ERR_REPEAT_TIMEOUT;
  4906.                   return(ERR_EOF);
  4907.               }
  4908.           }
  4909.  
  4910.           the following code is correct.
  4911.  
  4912.  
  4913.  
  4914.  
  4915.  
  4916.                                                           CommInterfaceRead
  4917.  
  4918.  
  4919.  
  4920.                                                                          99
  4921.  
  4922.  
  4923.           if (c == ASBUFREMPTY) {
  4924.  
  4925.               /* if still no character, check for timeout. */
  4926.               time(&seconds);
  4927.               if (seconds >= r_timeout) {
  4928.                   *info = ERR_REPEAT_TIMEOUT;
  4929.                   return(ERR_EOF);
  4930.               }
  4931.  
  4932.           } else {
  4933.               /* Error ASINVPORT or ASNOTSETUP occurred. */
  4934.               *info = c;
  4935.               return(ERR_COMM_PACKAGE);
  4936.           }
  4937.  
  4938.           This way if an error besides ASBUFREMPTY is returned,
  4939.           ERR_COMM_PACKAGE is returned by CommInterfaceRead.
  4940.  
  4941.           Finally, the last change is done for speed.  A call is made to
  4942.           'asigetc' before setting up for a timeout.  If there is a
  4943.           character, it is returned without the overhead of setting up for
  4944.           a repeating timeout.  If there is not a character, the time
  4945.           required to set up for a timeout is ok since the code will enter
  4946.           a polling loop anyway.  At this point I would like to show the
  4947.           complete implementation that supports Repeating Timeouts. 
  4948.           (Remember this implementation doesn't support Ending Timeouts).
  4949.  
  4950.  
  4951.  
  4952.  
  4953.  
  4954.  
  4955.  
  4956.  
  4957.  
  4958.  
  4959.  
  4960.  
  4961.  
  4962.  
  4963.  
  4964.  
  4965.  
  4966.  
  4967.  
  4968.  
  4969.  
  4970.  
  4971.                                                           CommInterfaceRead
  4972.  
  4973.  
  4974.  
  4975.                                                                         100
  4976.  
  4977.           /********************************************************/
  4978.               int
  4979.           CommInterfaceRead (com, r_timeout, e_timeout, info, opts)
  4980.               int com;         /* The AutoLibrary communication port. */
  4981.               long r_timeout;  /* The repeating timeout. */
  4982.               long e_timeout;  /* The ending timeout. */
  4983.               int *info;
  4984.               char *opts;      /* Options. */
  4985.           /********************************************************/
  4986.           {
  4987.           int c;
  4988.           long seconds;
  4989.  
  4990.               /* Start out with no errors. */
  4991.               *info = ERR_OK;
  4992.  
  4993.               /* Try to get a character without setting up
  4994.                                                     for a timeout. */
  4995.               c = asigetc (comlist[com]->hw_port);
  4996.               if ((c >=0) && (c <= 0xFF)) {
  4997.                   EveryChar(c);
  4998.                   return(c);
  4999.               }
  5000.  
  5001.               if (c == ASINVPORT) {
  5002.                   *info = ASINVPORT;
  5003.                   return(ERR_COMM_PACKAGE);
  5004.               }
  5005.  
  5006.               if (c == ASNOTSETUP) {
  5007.                   *info = ASNOTSETUP;
  5008.                   return(ERR_COMM_PACKAGE);
  5009.               }
  5010.  
  5011.               /* A timeout is required so set up for it. */
  5012.               time(&seconds);
  5013.               if (r_timeout < seconds)
  5014.                   r_timeout = r_timeout + seconds;
  5015.  
  5016.               while (1 > 0) {
  5017.  
  5018.                   /* Try to get a character. */
  5019.                   c = asigetc (comlist[com]->hw_port);
  5020.                   if ((c >=0) && (c <= 0xFF)) {
  5021.                       EveryChar(c);
  5022.                       return(c);
  5023.                   }
  5024.  
  5025.  
  5026.                                                           CommInterfaceRead
  5027.  
  5028.  
  5029.  
  5030.                                                                         101
  5031.  
  5032.  
  5033.                   if (c == ASBUFREMPTY) {
  5034.  
  5035.                       time (&seconds);
  5036.                       if (seconds >= r_timeout) {
  5037.                           *info = ERR_REPEAT_TIMEOUT;
  5038.                           return(ERR_EOF);
  5039.                       }
  5040.  
  5041.                   } else {
  5042.                       /* Error ASINVPORT or ASNOTSETUP occurred. */
  5043.                       *info = c;
  5044.                       return(ERR_COMM_PACKAGE);
  5045.                   }
  5046.               }
  5047.  
  5048.               opts = opts; /* for compiler */
  5049.  
  5050.               /* Nothing should reach here but if it does... */
  5051.               *info = c;
  5052.               return(ERR_COMM_PACKAGE);
  5053.           }
  5054.  
  5055.           Now, Ending Timeout support needs to be added to
  5056.           CommInterfaceRead.  This is simple.  The following test needs to
  5057.           be added just inside the while loop.
  5058.  
  5059.           /* Do not try to get a character if an ending timeout has
  5060.           occurred. */
  5061.           time(&seconds);
  5062.           if (seconds >= e_timeout) {
  5063.               *info = ERR_ENDING_TIMEOUT;
  5064.               return(ERR_EOF);
  5065.           }
  5066.  
  5067.           This test also needs to occur before the first call to 'asigetc'
  5068.           in case characters are continously received when an ending
  5069.           timeout should occur.
  5070.  
  5071.           Now the complete and final implementation of CommInterfaceRead
  5072.           looks like the following.
  5073.  
  5074.  
  5075.  
  5076.  
  5077.  
  5078.  
  5079.  
  5080.  
  5081.                                                           CommInterfaceRead
  5082.  
  5083.  
  5084.  
  5085.                                                                         102
  5086.  
  5087.  
  5088.           /********************************************************/
  5089.               int
  5090.           CommInterfaceRead (com, r_timeout, e_timeout, info, opts)
  5091.               int com;         /* The AutoLibrary communication port. */
  5092.               long r_timeout;  /* The repeating timeout. */
  5093.               long e_timeout;  /* The ending timeout. */
  5094.               int *info;
  5095.               char *opts;      /* Options. */
  5096.           /********************************************************/
  5097.           {
  5098.           int c;
  5099.           long seconds;
  5100.  
  5101.               /* Start out with no errors. */
  5102.               *info = ERR_OK;
  5103.  
  5104.               /* Have to check for an ending timeout. */
  5105.               time(&seconds);
  5106.               if (seconds >= e_timeout) {
  5107.                   *info = ERR_ENDING_TIMEOUT;
  5108.                   return(ERR_EOF);
  5109.               }
  5110.  
  5111.               /* Try to get a character without setting up
  5112.                                                    for a timeout. */
  5113.               c = asigetc (comlist[com]->hw_port);
  5114.               if ((c >=0) && (c <= 0xFF)) {
  5115.                   EveryChar(c);
  5116.                   return(c);
  5117.               }
  5118.  
  5119.               if (c == ASINVPORT) {
  5120.                   *info = ASINVPORT;
  5121.                   return(ERR_COMM_PACKAGE);
  5122.               }
  5123.  
  5124.               if (c == ASNOTSETUP) {
  5125.                   *info = ASNOTSETUP;
  5126.                   return(ERR_COMM_PACKAGE);
  5127.               }
  5128.  
  5129.               /* A timeout is required so set up for it. */
  5130.               time(&seconds);
  5131.               if (r_timeout < seconds)
  5132.                   r_timeout = r_timeout + seconds;
  5133.  
  5134.  
  5135.  
  5136.                                                           CommInterfaceRead
  5137.  
  5138.  
  5139.  
  5140.                                                                         103
  5141.  
  5142.               while (1 > 0) {
  5143.  
  5144.                   /*Do not try to get a character if an ending
  5145.                     timeout has occurred.*/
  5146.                   time (&seconds);
  5147.                   if (seconds >= e_timeout) {
  5148.                       *info = ERR_ENDING_TIMEOUT;
  5149.                       return(ERR_EOF);
  5150.                   }
  5151.  
  5152.                   /* Try to get a character. */
  5153.                   c = asigetc (comlist[com]->hw_port);
  5154.                   if ((c >=0) && (c <= 0xFF)) {
  5155.                       EveryChar(c);
  5156.                       return(c);
  5157.                   }
  5158.  
  5159.                   if (c == ASBUFREMPTY) {
  5160.  
  5161.                       time (&seconds);
  5162.                       if (seconds >= r_timeout) {
  5163.                           *info = ERR_REPEAT_TIMEOUT;
  5164.                           return(ERR_EOF);
  5165.                       }
  5166.  
  5167.                   } else {
  5168.                       /* Error ASINVPORT or ASNOTSETUP occurred. */
  5169.                       *info = c;
  5170.                       return(ERR_COMM_PACKAGE);
  5171.                   }
  5172.               }
  5173.  
  5174.               opts = opts; /* for compiler */
  5175.  
  5176.               /* Nothing should reach here but if it does... */
  5177.               *info = c;
  5178.               return(ERR_COMM_PACKAGE);
  5179.           }
  5180.  
  5181.           It was easy for CommInterfaceRead to support Ending Timeouts
  5182.           because it is the responsibility of the calling routine to set up
  5183.           for it.  CommInterfaceRead simply gets (in the 'e_timeout'
  5184.           parameter) a system time value in total seconds from Jan 1, 1970. 
  5185.           An Ending Timeout occurs when the current system time is greater
  5186.           than or equal to 'e_timeout'.
  5187.  
  5188.  
  5189.  
  5190.  
  5191.                                                           CommInterfaceRead
  5192.  
  5193.  
  5194.  
  5195.                                                                         104
  5196.  
  5197.           If you would like to know more about the callers responsibility
  5198.           for Ending Timeouts, take a look at the source code for
  5199.           AvidSendSearch.  AvidSendSearch makes calls to AvidRead from
  5200.           inside a while loop.  (AvidRead passes the 'r_timeout' and
  5201.           'e_timeout' values directly to CommInterfaceRead).  Before the
  5202.           while loop, the current system time is added to the 'e_timeout'
  5203.           parameter.  The 'e_timeout' parameter is then constant for each
  5204.           call to AvidRead, which makes it possible to support Ending
  5205.           Timeouts.
  5206.  
  5207.           See Also
  5208.  
  5209.           AvidRead, Actual source code.
  5210.  
  5211.  
  5212.  
  5213.  
  5214.  
  5215.  
  5216.  
  5217.  
  5218.  
  5219.  
  5220.  
  5221.  
  5222.  
  5223.  
  5224.  
  5225.  
  5226.  
  5227.  
  5228.  
  5229.  
  5230.  
  5231.  
  5232.  
  5233.  
  5234.  
  5235.  
  5236.  
  5237.  
  5238.  
  5239.  
  5240.  
  5241.  
  5242.  
  5243.  
  5244.  
  5245.  
  5246.                                                           CommInterfaceRead
  5247.  
  5248.  
  5249.  
  5250.                                                                         105
  5251.  
  5252.  
  5253.           CommInterfaceSend - Send Character
  5254.  
  5255.           err = CommInterfaceSend(com, bef, bet, s, len,
  5256.                                                 (int *)&add_info, opts)
  5257.  
  5258.           Parameter Description
  5259.  
  5260.           int err;       -- Error code.
  5261.  
  5262.           int com;       -- The AutoLibrary communication port.
  5263.  
  5264.           int bef;       -- The number of milliseconds to delay before
  5265.                          sending the first character.
  5266.  
  5267.           int bet;       -- The number of milliseconds to delay between
  5268.                          each character.
  5269.  
  5270.           char *s;       -- The string to send.
  5271.  
  5272.           int len;       -- The length of the string to send.  This value
  5273.                          may not equal strlen(s) because of null characters
  5274.                          in the string.
  5275.  
  5276.           int *add_info; -- Additional return information.
  5277.  
  5278.           char *opts;    -- Options.
  5279.  
  5280.           Options
  5281.  
  5282.           See AvidSend
  5283.  
  5284.           Return Codes
  5285.  
  5286.           ERR_OK              -- No error occurred.
  5287.  
  5288.           ERR_COMM_PACKAGE    -- This error occurs when the communication
  5289.                               package cannot send to the communication port
  5290.                               correctly.  When this error occurs, the
  5291.                               parameter 'add_info' will contain the actual
  5292.                               error returned by the communication package.
  5293.  
  5294.           Additional Information Return Codes
  5295.  
  5296.           ERR_OK         -- No error occurred.
  5297.  
  5298.  
  5299.  
  5300.  
  5301.                                                           CommInterfaceSend
  5302.  
  5303.  
  5304.  
  5305.                                                                         106
  5306.  
  5307.           <system err>   -- When ERR_COMM_PACKAGE is returned, 'add_info'
  5308.                          contains the actual error returned by the
  5309.                          communication package.
  5310.  
  5311.           Description
  5312.  
  5313.           This routine is used to send characters out the communication
  5314.           port.  Your code must not call this routine directly.  This
  5315.           routine will need to be modified to support your communication
  5316.           package.  See the System Requirements section for a list of
  5317.           supported communication packages.
  5318.  
  5319.           Porting to other communication packages
  5320.  
  5321.           The following sample source code is written to interface with the
  5322.           Greenleaf CommLib.  To support a different communication package,
  5323.           use this code as a template, then code according to the
  5324.           specifications of the communication package.
  5325.  
  5326.           This routine is easy to port.  A call is made to 'asiputc' inside
  5327.           a 'for' loop for each character to be sent.  The delay before
  5328.           value is done outside of the loop, and the delay between is done
  5329.           inside the 'for' loop.
  5330.  
  5331.  
  5332.  
  5333.  
  5334.  
  5335.  
  5336.  
  5337.  
  5338.  
  5339.  
  5340.  
  5341.  
  5342.  
  5343.  
  5344.  
  5345.  
  5346.  
  5347.  
  5348.  
  5349.  
  5350.  
  5351.  
  5352.  
  5353.  
  5354.  
  5355.  
  5356.                                                           CommInterfaceSend
  5357.  
  5358.  
  5359.  
  5360.                                                                         107
  5361.  
  5362.           /********************************************************/
  5363.               int
  5364.           CommInterfaceSend (com, bef, bet, s, len, info, opts)
  5365.               int com; /* The AutoLibrary communication port. */
  5366.               int bef; /* The number of milliseconds to delay before       
  5367.                    sending first character. */
  5368.               int bet; /* The number of milliseconds to delay between each
  5369.                           character. */
  5370.               char *s; /* The string to send. */
  5371.               int len; /* The length of the string. May not equal
  5372.                           strlen(s) because of null characters in the
  5373.                           string. */
  5374.               int *info;
  5375.               char *opts; /* Options. */
  5376.           /********************************************************/
  5377.           {
  5378.           int i, status;
  5379.  
  5380.               opts = opts; /* for compiler */
  5381.  
  5382.               /* Start out with no errors. */
  5383.               *info = ERR_OK;
  5384.  
  5385.               /* The delay before the first character sent. */
  5386.               delay (bef);
  5387.  
  5388.               for (i=0; i<len; i++) {
  5389.  
  5390.                   /* The delay before the first character sent. */
  5391.                   delay (bet);
  5392.  
  5393.                   status = asiputc (comlist[com]->hw_port, s[i]);
  5394.                   if (status != ASSUCCESS) {
  5395.                       *info = status;
  5396.                       return(ERR_COMM_PACKAGE);
  5397.                   }
  5398.               }
  5399.  
  5400.               return(ERR_OK);
  5401.           }
  5402.  
  5403.           See Also
  5404.  
  5405.           AvidSend, Actual source code.
  5406.  
  5407.  
  5408.  
  5409.  
  5410.  
  5411.                                                           CommInterfaceSend
  5412.